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