[coreboot] cbfs for safe flashing

Ed Swierk eswierk at aristanetworks.com
Wed Jul 14 08:44:35 CEST 2010

Hi folks,

I'm using Coreboot to implement an old-school Linux-as-bootloader for
a prototype board, which has an 8-MByte SPI flash attached to an AMD
SB800 southbridge. I'd like to take advantage of that nice roomy
flash, as well as the normal/fallback capabilities of Coreboot and the
layout and partial-rewrite features of flashrom, to provide a safe
firmware upgrade path for end users.

Ideally I'd divide up the flash so that the normal Coreboot+payload
are separate from the fallback Coreboot+payload and bootblock. The end
user would only rewrite the normal Coreboot+payload. If the rewrite
fails leaving the normal area of the flash completely scrambled, the
board would still boot using the fallback Coreboot+payload. And for
extra credit, I'd try to put the critical fallback bits in an area of
the flash that can be turned read-only once it's programmed at the

Following the flashrom layout format, here's how I imagine
partitioning the flash:

00000000:003fffff normal+payload
00400000:ffffffff fallback+payload+bootblock

Following Patrick's helpful recipe
I figured out how to build a rom image with a cbfs containing normal
and fallback files. Unfortunately the build system insists on placing
each new file at the beginning of the free space; I didn't see any
obvious way to convince cbfstool to leave a gap after normal+payload
and place the fallback files at 00400000. I hacked around this by
creating a dummy pad file and adding it before the fallback files. Is
there a better way to do this?

The next issue I encountered is that when I test my scheme by erasing
the 00000000:003fffff region, Coreboot takes approximately forever to
locate the fallback files. In cbfs, information about each file is
stored in a header along with the file itself. To locate a file,
Coreboot starts at the first file's header and hops from one to the
next until it finds a matching filename. If instead of a header it
finds gibberish, it doesn't throw up its hands in despair; rather, it
goes into PRESS PLAY ON TAPE mode, scanning along until it either
finds a header signature or hits the end of the rom. At this early
stage of the boot process, caches and other such niceties aren't
enabled; on my board, each iteration in the walkcbfs loop causes ~75
SPI reads, yielding a scan rate of ~175kB/sec.

Placing the fallback files before the normal ones doesn't help,
because the bootblock needs to discover that the normal files are AWOL
before deciding to use the fallback. Increasing the cbfs file
alignment from the default of 64 bytes is more promising, allowing the
scan to take much bigger hops. I tried bumping it up to 4096 bytes and
ran into several bugs in cbfstool and walkcbfs, which assume that the
bootblock region is larger than the alignment in deciding when to
terminate the scan. While I'm sure these issues can be fixed, the
whole flash-as-tape thing bothers me. In my scheme, I've decided ahead
of time where the files are supposed to reside. A file's header is
either there or it isn't; there's no point wasting time scanning the
entire flash in the vain hope that the file is actually present, just
in an unexpected location.

I'm thinking of extending the cbfs format to allow more than one
top-level header in the bootblock. In my scheme, there would be two:
one pointing to the first normal file, and another pointing to the
first fallback file. Searching for a file would involve scanning each
series of files linked from the headers in the bootblock, and would
simply terminate if no matching filename were found in any of them.

This implies changing cbfstool and any code in Coreboot that touches
cbfs. Before I jump off the deep end, is there an easier or better way
to achieve this?


More information about the coreboot mailing list