I'd like to introduce a reasonably safe way to detect whether an image is a coreboot image.
Goals: - Easy to implement - Good for visual inspection of a image file with hexdump - Fixed location to make detection easy - Independence of the format of the image data - Reusable even if we decide to change the image data format completely
The existing solutions and approached do not fulfill all (or even any) of the goals above.
Proposal: Use the top 8 bytes of an image to store a short signature and a pointer to the real data. If the signature is 4 bytes and the pointer is 4 bytes, they fit exactly into the range 0xfffffff8-0xffffffff. The reset vector lives at 0xfffffff0 and it is a jump instruction with immediate operand. The instruction is 1 byte, the operand is 2 bytes (well, 4 bytes in reality due to binutils workarounds, but as the code is 16bit, only the first two bytes are evaluated). The space after the reset vector is not usable for code because you could only fit ~2-3 instructions there before needing another jump and that would complicate things a lot. So anything from 0xfffffff3 onwards (0xfffffff5 onwards if you consider the binutils workaround) is fair game for a signature or any other helpful construct. The LAR utility stores the 32-bit length of the archive at 0xfffffff4. That means the space 0xfffffff8-0xffffffff is up for grabs.
We could use the top 8 bytes for the following signature: 0xfffffff8-0xfffffffb: String (not NULL terminated) 'cb30' 0xfffffffc-0xffffffff: Relative location/pointer to a to-be-designed struct
This has the advantage of separating the information storage format from locating the information. If the string is 'cb30', follow the pointer and try to understand the storage format. If you can't decipher the storage format, you know that it is a coreboot image with an unsupported/unknown information storage format and you can tell the user to upgrade flashrom or whatever tool he/she is using to work on that image. We could even use the pointer to point to existing image information in v2 (which is currently searched for with exceessively ugly heuristics) and point to a LAR entry in v3 as needed.
Thoughts? Comments? The v3 patch below illustrates the idea, but it does not yet fill in the pointer.
Index: arch/x86/stage0_common.S =================================================================== --- arch/x86/stage0_common.S (Revision 1065) +++ arch/x86/stage0_common.S (Arbeitskopie) @@ -156,10 +156,12 @@ * instead of the weird 16 bit relocations that binutils does not * handle consistenly between versions because they are used so rarely. */ -.byte 0 + /* 3 filler bytes to have the signature at 0xfffff8. */ +.byte 0,0,0
-/* Date? ID string? We might want to put something else in here. */ -.ascii DATE +/* Signature together with a pointer to a struct with more information. */ +.ascii "cb30" +.long 0
/* Checksum. */ /* .word 0 */
Regards, Carl-Daniel
Carl-Daniel Hailfinger wrote:
I'd like to introduce a reasonably safe way to detect whether an image is a coreboot image.
Goals:
- Easy to implement
- Good for visual inspection of a image file with hexdump
- Fixed location to make detection easy
- Independence of the format of the image data
- Reusable even if we decide to change the image data format completely
The existing solutions and approached do not fulfill all (or even any) of the goals above.
Proposal: Use the top 8 bytes of an image to store a short signature and a pointer to the real data. If the signature is 4 bytes and the pointer is 4 bytes, they fit exactly into the range 0xfffffff8-0xffffffff. The reset vector lives at 0xfffffff0 and it is a jump instruction with immediate operand. The instruction is 1 byte, the operand is 2 bytes (well, 4 bytes in reality due to binutils workarounds, but as the code is 16bit, only the first two bytes are evaluated). The space after the reset vector is not usable for code because you could only fit ~2-3 instructions there before needing another jump and that would complicate things a lot. So anything from 0xfffffff3 onwards (0xfffffff5 onwards if you consider the binutils workaround) is fair game for a signature or any other helpful construct. The LAR utility stores the 32-bit length of the archive at 0xfffffff4. That means the space 0xfffffff8-0xffffffff is up for grabs.
We could use the top 8 bytes for the following signature: 0xfffffff8-0xfffffffb: String (not NULL terminated) 'cb30' 0xfffffffc-0xffffffff: Relative location/pointer to a to-be-designed struct
This has the advantage of separating the information storage format from locating the information. If the string is 'cb30', follow the pointer and try to understand the storage format. If you can't decipher the storage format, you know that it is a coreboot image with an unsupported/unknown information storage format and you can tell the user to upgrade flashrom or whatever tool he/she is using to work on that image. We could even use the pointer to point to existing image information in v2 (which is currently searched for with exceessively ugly heuristics) and point to a LAR entry in v3 as needed.
Thoughts? Comments?
If you do this, then you can get rid of the length at 0xfffffff4 and put the pointer there. All the ROM information should be contained in one place. The pointer should point to a master information header, including, but not limited to:
Magic ROM size block alignment start of the LAR data in the ROM (it might not always be at 0)
In addition, the structure could contain things like:
Date/time the ROM was created Description (e.g. "CBV3+coreinfo") Target architecture information Flashrom identifiers, etc, etc.
I think its fine to have one header to rule them all - LAR information can probably coexist with the other stuff, even if it is unused in v2. if it is a concern, you can probably turn the master header into a list of lists (e.g - magic, pointer to coreboot header, pointer to LAR header) but I think thats probably needs more real estate then we want to spend.
LAR desperately needs this - a master header would solve problems in multiple fields at once.
Jordan
Jordan Crouse wrote:
LAR desperately needs this - a master header would solve problems in multiple fields at once.
It goes directly against one original design goal of lar that I consider to be essential (the larball is a series of independent files) and I do not understand all the benefits.
This lar feature comes from the desire to support the use case of replacing single files in the lar in flash without any modifications being needed in any other part of the flash chip.
One way to preserve that goal while still providing the information you desire would be to store any master header in a separate file in the lar.
I think it is important to keep the non-structure of larballs.
//Peter
On 07.12.2008 03:42, Peter Stuge wrote:
Jordan Crouse wrote:
LAR desperately needs this - a master header would solve problems in multiple fields at once.
It goes directly against one original design goal of lar that I consider to be essential (the larball is a series of independent files) and I do not understand all the benefits.
This lar feature comes from the desire to support the use case of replacing single files in the lar in flash without any modifications being needed in any other part of the flash chip.
One way to preserve that goal while still providing the information you desire would be to store any master header in a separate file in the lar.
Storing the LAR size in the boot block is irrelevant for the LAR utility, but absolutely essential for booting. There's no other way to find out where to start scanning for LAR members. (In theory, we could start scanning at 4G-16M, but I doubt anybody wants to wait for up to 16 million accesses before the first LAR member is found. By the way, for future boards (especially GA-M57SLI) in v3 we will need another header field: Mappable size. It is pointless to scan memory where a chip is not mapped even if the chip would theoretically occupy that area.
I think it is important to keep the non-structure of larballs.
As long as the boot process can easily determine all the info it needs, that is OK with me.
Regards, Carl-Daniel
Peter Stuge wrote:
Jordan Crouse wrote:
LAR desperately needs this - a master header would solve problems in multiple fields at once.
It goes directly against one original design goal of lar that I consider to be essential (the larball is a series of independent files) and I do not understand all the benefits.
That might have been the original goal, but its just simply not the case in reality. Having to put the bootblock in a fixed position completely destroys the theory of a pure archive. And Ron has requested that we be able to support LAR components in fixed locations within the ROM, which will further emphasis the need for a fully formed ROM from the word go.
And really, this isn't a bad thing - the logical output of the coreboot build is a valid ROM (i.e - properly organized bits that can be directly written to the hardware without further modification). LAR still plays an important part here because both coreboot and the userland utilities desperately need a filesystem like organization within the ROM.
One way to preserve that goal while still providing the information you desire would be to store any master header in a separate file in the lar.
There are a number of problems with that approach - one, it doesn't work with v2, which was an important feature of Carl-Daniel's design. Two, it ends up wasting (eraseblock - sizeof(lar header file)) bytes on every ROM. Thirdly, coreboot and the LAR utilities would still have to know the size of the ROM and the location of the first LAR entry, so information has to be written to the bootblock regardless. The bootblock is valuable here because it is in a known fixed location, and both coreboot and the LAR utility can easily communicate with one another through it.
I think it is important to keep the non-structure of larballs.
Can you explain why in more detail? Do you have some examples?
Jordan
Hi,
Just a note. At the end of the flash, there is info for ROM bootstraps. VIA has it as a pointer on 0xffffffd0 (IIRC). nVidia & SiS has something too.
Rudolf
On 07.12.2008 09:33, Rudolf Marek wrote:
Hi,
Just a note. At the end of the flash, there is info for ROM bootstraps. VIA has it as a pointer on 0xffffffd0 (IIRC). nVidia & SiS has something too.
Yes, and that ROM bootstrap info location varies. It is always in the top 256 bytes, but never in the top 16 bytes. That's why I explicitly chose the top 8 bytes.
Regards, Carl-Daniel