[coreboot] [RFC] Configuration Data File Format

Carl-Daniel Hailfinger c-d.hailfinger.devel.2006 at gmx.net
Wed Jun 3 04:52:55 CEST 2009

Since the topic of optimal flash usage for configuration data comes up
repeatedly, I'd like to propose a flash-friendly and LAR/CBFS compatible
way to store and update configuration data.

The CDFF data is stored inside an uncompressed LAR/CBFS archive member
which occupies a full flash erase block, either with the start of the
header at the start of the erase block or with the start of the data
section at the start of the erase block.

The CDFF file format is as follows:

File Format header:
4 bytes magic header "CDFF"
4 bytes total length of CDFF area excluding file header

Configuration Data header:
2 bytes magic header "CD"
2 bytes version number of configuration data, at least 0x0001 (0x0000
means invalid)
4 bytes total length of Configuration Data excluding Configuration Data

Configuration Item header (version 0x0001):
2 bytes magic header "CI"
2 bytes data type, must not be 0x0000 (which is reserved)
4 bytes length of Configuration Item
n bytes of Configuration Item content

Each header is aligned at a 4 byte boundary.

The File Format header exists exactly once at the start.
Directly after the File Format header, the first Configuration Data
header starts. It is a "container" for multiple Configuration Items. The
version number has to be at least 0x0001. To mark the Configuation Data
as invalid, the version number is set to 0x0000 which is a
flash-friendly operation possible without erase. If the version number
is 0x0000, the reader skips over CD total length bytes starting after
the header and looks for the next CD header aligned to the next 4 byte
Directly after the Configuration Data header, the first Configuration
Item header starts. It holds a single configuration item or its
description. The CI data type MSB is 0 if the data is a value and 1 for
the matching (null-terminated) name/description. After the data there is
the next CI header aligned at the next 4 byte boundary.

If you need to update the data, simply write a new CD container with CI
data directly after the end of the last valid CD container. If the write
was successful, mark the previous container as invalid. If not, the old
container will still be valid and everything is OK.
If there's not enough room left for a new CD container, erase the whole
block and write a new CDFF header, CD header and all CIs.

This scheme keeps flash wear at a minium, has safe updates (except in
the case where all space is used up and the block has to be erased), is
fast and easy to walk and extensible enough to last a lifetime.

Example file:
0x43444646 (CDFF magic)
0x00000FF8 (eraseblockisze 4096 - headersize 8)
0x4344 (CD magic)
0x0001 (version)
0xbla (CD length)
0x4349 (CI magic)
0x0001 (data type, data)
0x00000013 (CI length)
"hda1:/boot/vmlinux\0" (data)
0xff (padding)
0x4349 (CI magic)
0x8001 (data type, description)
0x00000009 (CI length)
0xffffff (padding)
0x4349 (CI magic)
0x0002 (data type, data)
0x00000018 (CI length)
"acpi=off root=/dev/sda2\0" (data)
0x4349 (CI magic)
0x8002 (data type, description)
0x0000000B (CI length)
0xff (padding)

Since the CI name is (optionally) stored along with the CI data, running
out of data types is only possible if we have more than 32767 different
CIs. Any config reader can just search for the name if it wants some data.
The naming also avoids having a central registry about which data type
has which number, an annoyance present with our current NVRAM scheme.

A checksum is possible (even in a mostly flash-friendly way), but it
would have cluttered this design doc.



More information about the coreboot mailing list