coreboot-v2/documentation/cbfs.txt
<<
>>
Prefs
   1
   2Received: from www.crouse-house.com ([199.45.160.146]
   3        for coreboot@coreboot.org; Fri, 19 Dec 2008 23:11:59 +0100
   4From: Jordan Crouse <jordan@cosmicpenguin.net>
   5
   6
   7Greetings.  I apologize for the incompleteness of what I am about to 
   8discuss.  I was planning on working on it leisurely, but my employment 
   9circumstances changed and I've been trying to get it completed in a 
  10hurry before I had to leave it behind.
  11
  12I've been thinking a lot about LAR lately, and ways to make it more 
  13extensible and robust.  Marc and I have been trading ideas back and 
  14forth for a number of months, and over time a clear idea of what I 
  15wanted to do started to take shape.
  16
  17My goal was to add small things to LAR while retaining the overall 
  18scheme.  Over time, the scheme evolved slightly, but I think you'll find 
  19that it remains true to the original idea.  Below is the beginnings of 
  20an architecture document - I did it in text form, but if met with 
  21aclaim, it should be wikified.  This presents what I call CBFS - the 
  22next generation LAR for next generation Coreboot.  Its easier to 
  23describe what it is by describing what changed:
  24
  25A header has been added somewhere in the bootblock similar to Carl 
  26Daniel's scheme.  In addition to the coreboot information, the header 
  27reports the size of the ROM, the alignment of the blocks, and the offset 
  28of the first component in the CBFS.   The master header provides all 
  29the information LAR needs plus the magic number information flashrom needs.
  30
  31Each "file" (or component, as I style them) now has a type associated 
  32with it. The type is used by coreboot to identify the type of file that 
  33it is loading, and it can also be used by payloads to group items in the 
  34CBFS by type (i.e - bayou can ask for all components that are payloads).
  35
  36The header on each "file" (or component, as I like to style them) has 
  37been simplified - We now only store the length, the type, the checksum, 
  38and the offset to the data.  The name scheme remains the same.  The 
  39addtional information, which is component specific, has been moved to 
  40the component itself (see below).
  41
  42The components are arranged in the ROM aligned along the specified 
  43alignment from the master header - this is to facilitate partial re-write.
  44
  45Other then that, the LAR ideas remain pretty much the same.
  46
  47The plan for moving the metadata to the components is to allow many 
  48different kinds of components, not all of which are groked by coreboot. 
  49  However, there are three essential component types that are groked by 
  50coreboot, and they are defined:
  51
  52stage - the stage is being parsed from the original ELF, and stored in 
  53the ROM as a single blob of binary data.  The load address, start 
  54address, compression type and length are stored in the component sub-header.
  55
  56payload - this is essentially SELF in different clothing - same idea as 
  57SELF, with the sub-header as above.
  58
  59optionrom - This is in flux - right now, the optionrom is stored 
  60unadulterated and uncompressed, but that is likely to be changed.
  61
  62Following this email are two replies containing the v3 code and a new 
  63ROM tool to implement this respectively.  I told you that I was trying 
  64to get this out before I disappear, and I'm not kidding - the code is 
  65compile tested and not run-tested.  I hope that somebody will embrace 
  66this code and take it the rest of the way, otherwise it will die a 
  67pretty short death.
  68
  69I realize that this will start an awesome flamewar, and I'm looking 
  70forward to it.  Thanks for listening to me over the years - and good 
  71luck with coreboot.  When you all make a million dollars, send me a few 
  72bucks, will you?
  73
  74Jordan
  75
  76Coreboot CBFS Specification
  77Jordan Crouse <jordan@cosmicpenguin.net>
  78
  79= Introduction =
  80
  81This document describes the coreboot CBFS specification (from here
  82referred to as CBFS).  CBFS is a scheme for managing independent chunks
  83of data in a system ROM.  Though not a true filesystem, the style and
  84concepts are similar.
  85
  86
  87= Architecture =
  88
  89The CBFS architecture looks like the following:
  90
  91/---------------\ <-- Start of ROM
  92| /-----------\ | --|
  93| | Header    | |   |
  94| |-----------| |   |
  95| | Name      | |   |-- Component
  96| |-----------| |   |
  97| |Data       | |   |
  98| |..         | |   |
  99| \-----------/ | --|
 100|               |
 101| /-----------\ |
 102| | Header    | |
 103| |-----------| |
 104| | Name      | |
 105| |-----------| |
 106| |Data       | |
 107| |..         | |
 108| \-----------/ |
 109|               |
 110| ...           |
 111| /-----------\ |
 112| |           | |
 113| | Bootblock | |
 114| | --------- | |
 115| | Reset     | | <- 0xFFFFFFF0
 116| \-----------/ |
 117\---------------/
 118
 119
 120The CBFS architecture consists of a binary associated with a physical
 121ROM disk referred hereafter as the ROM. A number of independent of
 122components, each with a  header prepended on to data are located within
 123the ROM.  The components are nominally arranged sequentially, though they
 124are aligned along a pre-defined boundary.
 125
 126The bootblock occupies the last 20k of the ROM.  Within
 127the bootblock is a master header containing information about the ROM
 128including the size, alignment of the components, and the offset of the
 129start of the first CBFS component within the ROM.
 130
 131= Master Header =
 132
 133The master header contains essential information about the ROM that is
 134used by both the CBFS implementation within coreboot at runtime as well
 135as host based utilities to create and manage the ROM.  The master header
 136will be located somewhere within the bootblock (last 20k of the ROM).  A
 137pointer to the location of the header will be located at offset
 138-12 from the end of the ROM.  This translates to address 0xFFFFFFF4 on a
 139normal x86 system.  The pointer will be to physical memory somewhere
 140between - 0xFFFFB000 and 0xFFFFFFF0.  This makes it easier for coreboot
 141to locate the header at run time.  Build time utilities will
 142need to read the pointer and do the appropriate math to locate the header.
 143
 144The following is the structure of the master header:
 145
 146struct cbfs_header {
 147        unsigned int magic;
 148        unsigned int size;
 149        unsigned int align;
 150        unsigned int offset;
 151};
 152
 153The meaning of each member is as follows:
 154
 155'magic' is a 32 bit number that identifies the ROM as a CBFS type.  The 
 156magic
 157number is 0x4F524243, which is 'ORBC' in ASCII.
 158
 159'size' is the size of the ROM in bytes.  Coreboot will subtract 'size' from
 1600xFFFFFFFF to locate the beginning of the ROM in memory.
 161
 162'align' is the number of bytes that each component is aligned to within the
 163ROM.  This is used to make sure that each component is aligned correctly 
 164with
 165regards to the erase block sizes on the ROM - allowing one to replace a
 166component at runtime without disturbing the others.
 167
 168'offset' is the offset of the the first CBFS component (from the start of
 169the ROM).  This is to allow for arbitrary space to be left at the beginning
 170of the ROM for things like embedded controller firmware.
 171
 172= Bootblock =
 173The bootblock is a mandatory component in the ROM.  It is located in the 
 174last
 17520k of the ROM space, and contains, among other things, the location of the
 176master header and the entry point for the loader firmware.  The bootblock
 177does not have a component header attached to it.
 178
 179= Components =
 180
 181CBFS components are placed in the ROM starting at 'offset' specified in
 182the master header and ending at the bootblock.  Thus the total size 
 183available
 184for components in the ROM is (ROM size - 20k - 'offset').  Each CBFS
 185component is to be aligned according to the 'align' value in the header.
 186Thus, if a component of size 1052 is located at offset 0 with an 'align' 
 187value
 188of 1024, the next component will be located at offset 2048.
 189
 190Each CBFS component will be indexed with a unique ASCII string name of
 191unlimited size.
 192
 193Each CBFS component starts with a header:
 194
 195struct cbfs_file {
 196         char magic[8];
 197         unsigned int len;
 198         unsigned int type;
 199         unsigned int checksum;
 200         unsigned int offset;
 201};
 202
 203'magic' is a magic value used to identify the header.  During runtime,
 204coreboot will scan the ROM looking for this value.  The default magic is
 205the string 'LARCHIVE'.
 206
 207'len' is the length of the data, not including the size of the header and
 208the size of the name.
 209
 210'type' is a 32 bit number indicating the type of data that is attached.
 211The data type is used in a number of ways, as detailed in the section
 212below.
 213
 214'checksum' is a 32bit checksum of the entire component, including the
 215header and name.
 216
 217'offset' is the start of the component data, based off the start of the 
 218header.
 219The difference between the size of the header and offset is the size of the
 220component name.
 221
 222Immediately following the header will be the name of the component, 
 223which will
 224null terminated and 16 byte aligned.   The following picture shows the
 225structure of the header:
 226
 227/--------\  <- start
 228| Header |
 229|--------|  <- sizeof(struct cbfs_file)
 230| Name   |
 231|--------|  <- 'offset'
 232| Data   |
 233| ...    |
 234\--------/  <- start + 'offset' + 'len'
 235
 236== Searching Alogrithm ==
 237
 238To locate a specific component in the ROM, one starts at the 'offset'
 239specified in the CBFS master header.  For this example, the offset will
 240be 0.
 241
 242 From that offset, the code should search for the magic string on the
 243component, jumping 'align' bytes each time.  So, assuming that 'align' is
 24416, the code will search for the string 'LARCHIVE' at offset 0, 16, 32, etc.
 245If the offset ever exceeds the allowable range for CBFS components, then no
 246component was found.
 247
 248Upon recognizing a component, the software then has to search for the
 249specific name of the component.  This is accomplished by comparing the
 250desired name with the string on the component located at
 251offset + sizeof(struct cbfs_file).  If the string matches, then the 
 252component
 253has been located, otherwise the software should add 'offset' + 'len' to
 254the offset and resume the search for the magic value.
 255
 256== Data Types ==
 257
 258The 'type' member of struct cbfs_file is used to identify the content
 259of the component data, and is used by coreboot and other
 260run-time entities to make decisions about how to handle the data.
 261
 262There are three component types that are essential to coreboot, and so
 263are defined here.
 264
 265=== Stages ===
 266
 267Stages are code loaded by coreboot during the boot process.  They are
 268essential to a successful boot.   Stages are comprised of a single blob
 269of binary data that is to be loaded into a particular location in memory
 270and executed.   The uncompressed header contains information about how
 271large the data is, and where it should be placed, and what additional memory
 272needs to be cleared.
 273
 274Stages are assigned a component value of 0x10.  When coreboot sees this
 275component type, it knows that it should pass the data to a sub-function
 276that will process the stage.
 277
 278The following is the format of a stage component:
 279
 280/--------\
 281| Header |
 282|--------|
 283| Binary |
 284| ..     |
 285\--------/
 286
 287The header is defined as:
 288
 289struct cbfs_stage {
 290         unsigned int compression;
 291         unsigned long long entry;
 292         unsigned long long load;
 293         unsigned int len;
 294         unsigned int memlen;
 295};
 296
 297'compression' is an integer defining how the data is compressed.  There
 298are three compression types defined by this version of the standard:
 299none (0x0), lzma (0x1), and nrv2b (0x02), though additional types may be
 300added assuming that coreboot understands how to handle the scheme.
 301
 302'entry' is a 64 bit value indicating the location where  the program
 303counter should jump following the loading of the stage.  This should be
 304an absolute physical memory address.
 305
 306'load' is a 64 bit value indicating where the subsequent data should be
 307loaded.  This should be an absolute physical memory address.
 308
 309'len' is the length of the compressed data in the component.
 310
 311'memlen' is the amount of memory that will be used by the component when
 312it is loaded.
 313
 314The component data will start immediately following the header.
 315
 316When coreboot loads a stage, it will first zero the memory from 'load' to
 317'memlen'.  It will then decompress the component data according to the
 318specified scheme and place it in memory starting at 'load'.  Following that,
 319it will jump execution to the address specified by 'entry'.
 320Some components are designed to execute directly from the ROM - coreboot
 321knows which components must do that and will act accordingly.
 322
 323=== Payloads ===
 324
 325Payloads are loaded by coreboot following the boot process.
 326
 327Stages are assigned a component value of 0x20.  When coreboot sees this
 328component type, it knows that it should pass the data to a sub-function
 329that will process the payload.  Furthermore, other run time
 330applications such as 'bayou' may easily index all available payloads
 331on the system by searching for the payload type.
 332
 333
 334The following is the format of a stage component:
 335
 336/-----------\
 337| Header    |
 338| Segment 1 |
 339| Segment 2 |
 340| ...       |
 341|-----------|
 342| Binary    |
 343| ..        |
 344\-----------/
 345
 346The header is as follows:
 347
 348struct cbfs_payload {
 349         struct cbfs_payload_segment segments;
 350}
 351
 352The header contains a number of segments corresponding to the segments
 353that need to be loaded for the payload.
 354
 355The following is the structure of each segment header:
 356
 357struct cbfs_payload_segment {
 358         unsigned int type;
 359         unsigned int compression;
 360         unsigned int offset;
 361         unsigned long long load_addr;
 362         unsigned int len;
 363         unsigned int mem_len;
 364};
 365
 366'type' is the type of segment, one of the following:
 367
 368PAYLOAD_SEGMENT_CODE   0x45444F43   The segment contains executable code
 369PAYLOAD_SEGMENT_DATA   0x41544144   The segment contains data
 370PAYLOAD_SEGMENT_BSS    0x20535342   The memory speicfied by the segment
 371                                     should be zeroed
 372PAYLOAD_SEGMENT_PARAMS 0x41524150   The segment contains information for
 373                                     the payload
 374PAYLOAD_SEGMENT_ENTRY  0x52544E45   The segment contains the entry point
 375                                    for the payload
 376
 377'compression' is the compression scheme for the segment.  Each segment can
 378be independently compressed. There are three compression types defined by
 379this version of the standard: none (0x0), lzma (0x1), and nrv2b (0x02),
 380though additional types may be added assuming that coreboot understands
 381how to handle the scheme.
 382
 383'offset' is the address of the data within the component, starting from
 384the component header.
 385
 386'load_addr' is a 64 bit value indicating where the segment should be placed
 387in memory.
 388
 389'len' is a 32 bit value indicating the size of the segment within the
 390component.
 391
 392'mem_len' is the size of the data when it is placed into memory.
 393
 394The data will located immediately following the last segment.
 395
 396=== Option ROMS ===
 397
 398The third specified component type will be Option ROMs.  Option ROMS will
 399have component type '0x30'.  They will have no additional header, the
 400uncompressed binary data will be located in the data portion of the
 401component.
 402
 403=== NULL ===
 404
 405There is a 4th component type ,defined as NULL (0xFFFFFFFF).  This is
 406the "don't care" component type.  This can be used when the component
 407type is not necessary (such as when the name of the component is unique.
 408i.e. option_table).  It is recommended that all components be assigned a
 409unique type, but NULL can be used when the type does not matter.
 410
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.