Hi guys
I have some questions about stages / payload in coreboot-v2 and CBFS. First of all, there is no way to run a 64 bit payload today. So I wrote some code and now I'm able to parse and add a 64 bit elf in a cbfs rom, and run it as a payload in coreboot. Coreboot will switch to 64 bit mode then jump into the payload.
I can send a patch for review but it's not really clean code : - I need some memory to store the page translation tables before going to 64 bits. It's hardcoded to some unused (I hope) location. How can I allocate space in a generic way ? Is it possible to reuse the resource allocator for this ? - If the payload returns, I guess I shall switch back to protected mode. Under which circumstances a payload can return ? - When a payload is parsed and added in the CBFS rom, is there any way to know if this is 32 or 64 code ? I added a field elfclass in the cbfs_payload structure to keep the information.
Other question : what is the correct way to insert code running from ram (a stage) in the bootblock or at a fixed location ? In my case, after the CAR, coreboot will load the fallback or normal stage, then jump in it. I need to add a third one : a recover stage. If the user pushes a key, strap a jumper... then I go in recover stage, otherwise I continue as usual. I modified the newconfig/config.g to add a custom 'stage' rule. I'm able to add a 32 bit elf as a custom stage (I can provide a patch if interested).
But I need to be sure that this custom stage lives in the top block (64 KB) of my FWH (2MB). Is there any way to specify this ?
Regards, Thomas
Am 12.08.2009 23:45, schrieb Thomas Jourdan:
I can send a patch for review but it's not really clean code :
- I need some memory to store the page translation tables before going
to 64 bits. It's hardcoded to some unused (I hope) location. How can I allocate space in a generic way ? Is it possible to reuse the resource allocator for this ?
When the payload is running, all memory marked "free" in the memory map (see cbtable) is up for the payload to use. coreboot doesn't exist anymore at that point.
- If the payload returns, I guess I shall switch back to protected mode.
Under which circumstances a payload can return ?
We don't really support payloads that return. There was some work in that direction with bayou, but as far as I can tell, it isn't really specified yet. As for, when a payload can return, that's up to your payload. If you don't need it to return, it won't :-)
- When a payload is parsed and added in the CBFS rom, is there any way
to know if this is 32 or 64 code ? I added a field elfclass in the cbfs_payload structure to keep the information.
Sounds good to me, that's what the subheaders are for.
Other question : what is the correct way to insert code running from ram (a stage) in the bootblock or at a fixed location ? In my case, after
The bootblock should be left alone after it's generated. CBFS has nothing to do with it.
But I need to be sure that this custom stage lives in the top block (64 KB) of my FWH (2MB). Is there any way to specify this ?
Right now, the top 64kb are usually managed by the bootblock. The code that coreboot jumps to after CAR is also there, the stages in CBFS are the compressed RAM stages. So you'll have to shove your recovery stage into the bootblock "somehow". The easiest solution in the old buildsystem is probably to add another stage (besides failover/fallback/normal), and special case its build somehow (so the ram stage isn't built or linked). The new build system only supports building one variant for now, until we figured out how to properly do it with the capabilities CBFS gives us.
Patrick
Patrick, all
- When a payload is parsed and added in the CBFS rom, is there any way
to know if this is 32 or 64 code ? I added a field elfclass in the cbfs_payload structure to keep the information.
Sounds good to me, that's what the subheaders are for.
I just send some patches for 64 bits payloads. More details in them.
Other question : what is the correct way to insert code running from ram (a stage) in the bootblock or at a fixed location ? In my case, after
The bootblock should be left alone after it's generated. CBFS has nothing to do with it.
But I need to be sure that this custom stage lives in the top block (64 KB) of my FWH (2MB). Is there any way to specify this ?
Right now, the top 64kb are usually managed by the bootblock. The code that coreboot jumps to after CAR is also there, the stages in CBFS are the compressed RAM stages. So you'll have to shove your recovery stage into the bootblock "somehow". The easiest solution in the old buildsystem is probably to add another stage (besides failover/fallback/normal), and special case its build somehow (so the ram stage isn't built or linked). The new build system only supports building one variant for now, until we figured out how to properly do it with the capabilities CBFS gives us.
In my case CBFS is mandatory, I can not use the old buildsystem. I found a solution to solve my problem with CBFS. As I said, I need to have the bootblock and the recover stage in the top block of the FWH.
First of all, I reduced the size of the bootblock to 48 KB, which gives me 16 KB for the recover stage, which is enough. Then, I modified the cbfstool to add files backwards. In CBFS, when a file is added, the free space is split in 2. The "left" part (with lowest offset) will hold the file we are adding, and the right part (with highest offset) will be the remaining free space. I swapped this so files are inserted backwards. This way, if I add the recover stage first, it will be right before the bootblock.
I don't know much for amd southbridges, but with intel SB, there is a top swap block bit in a register of the LPC bridge. This is usefull to backup and swap the topblock when updating the firmware. This way, there is always a valid bootblock, even if the power fails during update. In order to always be able to reflash, the top block must contain the bootblock and some code to recover.
It's easier to handle this kind of behaviour when files that compose the firmware are stored from the top of the FWH.
Regards, Thomas
I'll take that patch. It makes sense to fill the FLASH from the top down.
Thanks
ron
I'll take that patch. It makes sense to fill the FLASH from the top down.
My patch needs a little more work. File insertion is top down but file chain walk is still bottom up. This is bad because the file chain can easyly break. As a workaround I added a raw file search function : I search the FWH for CBFS file signature.
I'll try to inverse the file chain walk and send the patch.
Regards, Thomas
On Fri, Aug 21, 2009 at 10:42 AM, Thomas Jourdantjourdan@neuf.fr wrote:
I'll take that patch. It makes sense to fill the FLASH from the top down.
My patch needs a little more work. File insertion is top down but file chain walk is still bottom up. This is bad because the file chain can easyly break. As a workaround I added a raw file search function : I search the FWH for CBFS file signature.
Nope. If the file chain can break, that's a bug. How did that happen? The whole point of adding empty space is to ensure it won't break.
ron
Le vendredi 21 août 2009 à 10:56 -0700, ron minnich a écrit :
On Fri, Aug 21, 2009 at 10:42 AM, Thomas Jourdantjourdan@neuf.fr wrote:
I'll take that patch. It makes sense to fill the FLASH from the top down.
My patch needs a little more work. File insertion is top down but file chain walk is still bottom up. This is bad because the file chain can easyly break. As a workaround I added a raw file search function : I search the FWH for CBFS file signature.
Nope. If the file chain can break, that's a bug. How did that happen? The whole point of adding empty space is to ensure it won't break.
I did succeed breaking the file chain when updating my firmware. It was voluntary because I needed to test the robustness of my recovery procedure.
When you want to walk the file chain, you grab the first file offset from the cbfs master header. This gives you the first file cbfs header. Then with master header alignment, header offset and length, you can easily compute the offset of the next file.
If for any reason (let's say power failure during flash upgrade), a FWH's block, which contains a cbfs header, is erased, then the file chain is broken. You can not circumvent it. The only work around is to use a raw cbfs find file function, which parses the whole rom looking for the cbfs file signature.
Now let's take the case where only the top block is valid. The idea is to have bootblock and recover stage in this block. If the chain file walk starts from the bottom of the rom, you're dead : you won't find the beginning of the file chain, and you won't find your recover stage.
If the file chain walk is backward, from top to bottom, you'll find the recover stage (the first file), allowing you to restore your whole rom. Of course the file chain is still broken because the file following the recover stage is missing, but you were able to locate the first file, which really matters.
It's just an idea to make to cbfs code more robust in the case of recovery procedure.
Regards, Thomas
Thomas, interesting point. In other words, your code would make cbfs more robust in the event of a failed flash operation due to power fail or reset in the middle of flashing.
I don't know how well this could work in practice but it's intriguing.
OK, let's see that patch when it's ready :-)
ron