blob: 7ecc9014a1cb2e0a86bbbf514e17f6b0360b9c0c [file] [log] [blame]
Stefan Reinauer013c7cf2009-04-08 07:47:01 +00001
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
Stefan Reinauer14e22772010-04-27 06:56:47 +00007Greetings. 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
Stefan Reinauer013c7cf2009-04-08 07:47:01 +000010hurry before I had to leave it behind.
11
Stefan Reinauer14e22772010-04-27 06:56:47 +000012I'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
Stefan Reinauer013c7cf2009-04-08 07:47:01 +000015wanted to do started to take shape.
16
Stefan Reinauer14e22772010-04-27 06:56:47 +000017My 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
Stefan Reinauer013c7cf2009-04-08 07:47:01 +000023describe what it is by describing what changed:
24
Stefan Reinauer14e22772010-04-27 06:56:47 +000025A 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
Stefan Reinauer013c7cf2009-04-08 07:47:01 +000029the information LAR needs plus the magic number information flashrom needs.
30
Stefan Reinauer14e22772010-04-27 06:56:47 +000031Each "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
Peter Stuge450b23f2009-04-14 00:01:34 +000034CBFS by type (i.e - bayou can ask for all components that are payloads).
Stefan Reinauer013c7cf2009-04-08 07:47:01 +000035
Stefan Reinauer14e22772010-04-27 06:56:47 +000036The 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
Stefan Reinauer013c7cf2009-04-08 07:47:01 +000040the component itself (see below).
41
Stefan Reinauer14e22772010-04-27 06:56:47 +000042The components are arranged in the ROM aligned along the specified
Stefan Reinauer013c7cf2009-04-08 07:47:01 +000043alignment from the master header - this is to facilitate partial re-write.
44
45Other then that, the LAR ideas remain pretty much the same.
46
Stefan Reinauer14e22772010-04-27 06:56:47 +000047The 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
Stefan Reinauer013c7cf2009-04-08 07:47:01 +000050coreboot, and they are defined:
51
Stefan Reinauer14e22772010-04-27 06:56:47 +000052stage - 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
Stefan Reinauer013c7cf2009-04-08 07:47:01 +000054address, compression type and length are stored in the component sub-header.
55
Stefan Reinauer14e22772010-04-27 06:56:47 +000056payload - this is essentially SELF in different clothing - same idea as
Stefan Reinauer013c7cf2009-04-08 07:47:01 +000057SELF, with the sub-header as above.
58
Stefan Reinauer14e22772010-04-27 06:56:47 +000059optionrom - This is in flux - right now, the optionrom is stored
Stefan Reinauer013c7cf2009-04-08 07:47:01 +000060unadulterated and uncompressed, but that is likely to be changed.
61
Stefan Reinauer14e22772010-04-27 06:56:47 +000062Following 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
Stefan Reinauer013c7cf2009-04-08 07:47:01 +000067pretty short death.
68
Stefan Reinauer14e22772010-04-27 06:56:47 +000069I 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
Stefan Reinauer013c7cf2009-04-08 07:47:01 +000072bucks, will you?
73
74Jordan
75
Peter Stuge450b23f2009-04-14 00:01:34 +000076Coreboot CBFS Specification
Stefan Reinauer013c7cf2009-04-08 07:47:01 +000077Jordan Crouse <jordan@cosmicpenguin.net>
78
79= Introduction =
80
Peter Stuge450b23f2009-04-14 00:01:34 +000081This document describes the coreboot CBFS specification (from here
82referred to as CBFS). CBFS is a scheme for managing independent chunks
Stefan Reinauer013c7cf2009-04-08 07:47:01 +000083of data in a system ROM. Though not a true filesystem, the style and
84concepts are similar.
85
86
87= Architecture =
88
Peter Stuge450b23f2009-04-14 00:01:34 +000089The CBFS architecture looks like the following:
Stefan Reinauer013c7cf2009-04-08 07:47:01 +000090
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 Stuge450b23f2009-04-14 00:01:34 +0000120The CBFS architecture consists of a binary associated with a physical
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000121ROM 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
Peter Stuge450b23f2009-04-14 00:01:34 +0000129start of the first CBFS component within the ROM.
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000130
131= Master Header =
132
133The master header contains essential information about the ROM that is
Peter Stuge450b23f2009-04-14 00:01:34 +0000134used by both the CBFS implementation within coreboot at runtime as well
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000135as 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
Stefan Reinauer48ca7b22009-12-17 09:42:30 +0000138-4 from the end of the ROM. This translates to address 0xFFFFFFFC on a
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000139normal 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
Peter Stuge450b23f2009-04-14 00:01:34 +0000146struct cbfs_header {
David Hendricks90ca3b62012-11-16 14:48:22 -0800147 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 Reinauer013c7cf2009-04-08 07:47:01 +0000156
157The meaning of each member is as follows:
158
Stefan Reinauer14e22772010-04-27 06:56:47 +0000159'magic' is a 32 bit number that identifies the ROM as a CBFS type. The
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000160magic
161number is 0x4F524243, which is 'ORBC' in ASCII.
162
David Hendricks90ca3b62012-11-16 14:48:22 -0800163'version' is a version number for CBFS header. cbfs_header structure may be
164different if version is not matched.
165
166'romsize' is the size of the ROM in bytes. Coreboot will subtract 'size' from
Stefan Reinauer013c7cf2009-04-08 07:47:01 +00001670xFFFFFFFF to locate the beginning of the ROM in memory.
168
David Hendricks90ca3b62012-11-16 14:48:22 -0800169'bootblocksize' is the size of bootblock reserved in firmware image.
170
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000171'align' is the number of bytes that each component is aligned to within the
Stefan Reinauer14e22772010-04-27 06:56:47 +0000172ROM. This is used to make sure that each component is aligned correctly
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000173with
174regards to the erase block sizes on the ROM - allowing one to replace a
175component at runtime without disturbing the others.
176
Peter Stuge450b23f2009-04-14 00:01:34 +0000177'offset' is the offset of the the first CBFS component (from the start of
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000178the ROM). This is to allow for arbitrary space to be left at the beginning
179of the ROM for things like embedded controller firmware.
180
David Hendricks90ca3b62012-11-16 14:48:22 -0800181'architecture' describes which architecture (x86, arm, ...) this CBFS is created
182for.
183
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000184= Bootblock =
Stefan Reinauer14e22772010-04-27 06:56:47 +0000185The bootblock is a mandatory component in the ROM. It is located in the
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000186last
18720k of the ROM space, and contains, among other things, the location of the
188master header and the entry point for the loader firmware. The bootblock
189does not have a component header attached to it.
190
191= Components =
192
Peter Stuge450b23f2009-04-14 00:01:34 +0000193CBFS components are placed in the ROM starting at 'offset' specified in
Stefan Reinauer14e22772010-04-27 06:56:47 +0000194the master header and ending at the bootblock. Thus the total size
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000195available
Peter Stuge450b23f2009-04-14 00:01:34 +0000196for components in the ROM is (ROM size - 20k - 'offset'). Each CBFS
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000197component is to be aligned according to the 'align' value in the header.
Stefan Reinauer14e22772010-04-27 06:56:47 +0000198Thus, if a component of size 1052 is located at offset 0 with an 'align'
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000199value
200of 1024, the next component will be located at offset 2048.
201
Peter Stuge450b23f2009-04-14 00:01:34 +0000202Each CBFS component will be indexed with a unique ASCII string name of
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000203unlimited size.
204
Peter Stuge450b23f2009-04-14 00:01:34 +0000205Each CBFS component starts with a header:
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000206
Peter Stuge450b23f2009-04-14 00:01:34 +0000207struct cbfs_file {
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000208 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,
216coreboot will scan the ROM looking for this value. The default magic is
217the string 'LARCHIVE'.
218
219'len' is the length of the data, not including the size of the header and
220the size of the name.
221
222'type' is a 32 bit number indicating the type of data that is attached.
223The data type is used in a number of ways, as detailed in the section
224below.
225
226'checksum' is a 32bit checksum of the entire component, including the
227header and name.
228
Stefan Reinauer14e22772010-04-27 06:56:47 +0000229'offset' is the start of the component data, based off the start of the
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000230header.
231The difference between the size of the header and offset is the size of the
232component name.
233
Stefan Reinauer14e22772010-04-27 06:56:47 +0000234Immediately following the header will be the name of the component,
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000235which will
236null terminated and 16 byte aligned. The following picture shows the
237structure of the header:
238
239/--------\ <- start
240| Header |
Peter Stuge450b23f2009-04-14 00:01:34 +0000241|--------| <- sizeof(struct cbfs_file)
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000242| Name |
243|--------| <- 'offset'
244| Data |
245| ... |
246\--------/ <- start + 'offset' + 'len'
247
248== Searching Alogrithm ==
249
250To locate a specific component in the ROM, one starts at the 'offset'
Peter Stuge450b23f2009-04-14 00:01:34 +0000251specified in the CBFS master header. For this example, the offset will
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000252be 0.
253
254 From that offset, the code should search for the magic string on the
255component, jumping 'align' bytes each time. So, assuming that 'align' is
25616, the code will search for the string 'LARCHIVE' at offset 0, 16, 32, etc.
Peter Stuge450b23f2009-04-14 00:01:34 +0000257If the offset ever exceeds the allowable range for CBFS components, then no
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000258component was found.
259
260Upon recognizing a component, the software then has to search for the
261specific name of the component. This is accomplished by comparing the
262desired name with the string on the component located at
Stefan Reinauer14e22772010-04-27 06:56:47 +0000263offset + sizeof(struct cbfs_file). If the string matches, then the
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000264component
265has been located, otherwise the software should add 'offset' + 'len' to
266the offset and resume the search for the magic value.
267
268== Data Types ==
269
Peter Stuge450b23f2009-04-14 00:01:34 +0000270The 'type' member of struct cbfs_file is used to identify the content
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000271of the component data, and is used by coreboot and other
272run-time entities to make decisions about how to handle the data.
273
274There are three component types that are essential to coreboot, and so
275are defined here.
276
277=== Stages ===
278
279Stages are code loaded by coreboot during the boot process. They are
280essential to a successful boot. Stages are comprised of a single blob
281of binary data that is to be loaded into a particular location in memory
282and executed. The uncompressed header contains information about how
283large the data is, and where it should be placed, and what additional memory
284needs to be cleared.
285
286Stages are assigned a component value of 0x10. When coreboot sees this
287component type, it knows that it should pass the data to a sub-function
288that will process the stage.
289
290The following is the format of a stage component:
291
292/--------\
293| Header |
294|--------|
295| Binary |
296| .. |
297\--------/
298
299The header is defined as:
300
Peter Stuge450b23f2009-04-14 00:01:34 +0000301struct cbfs_stage {
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000302 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
310are three compression types defined by this version of the standard:
Patrick Georgi2f39eae2013-08-31 08:16:27 +0200311none (0x0), lzma (0x1), and nrv2b (0x02, deprecated), though additional
312types may be added assuming that coreboot understands how to handle the scheme.
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000313
314'entry' is a 64 bit value indicating the location where the program
315counter should jump following the loading of the stage. This should be
316an absolute physical memory address.
317
318'load' is a 64 bit value indicating where the subsequent data should be
319loaded. 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
324it is loaded.
325
326The component data will start immediately following the header.
327
328When 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
330specified scheme and place it in memory starting at 'load'. Following that,
331it will jump execution to the address specified by 'entry'.
332Some components are designed to execute directly from the ROM - coreboot
333knows which components must do that and will act accordingly.
334
335=== Payloads ===
336
337Payloads are loaded by coreboot following the boot process.
338
339Stages are assigned a component value of 0x20. When coreboot sees this
340component type, it knows that it should pass the data to a sub-function
341that will process the payload. Furthermore, other run time
342applications such as 'bayou' may easily index all available payloads
343on the system by searching for the payload type.
344
345
346The 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
358The header is as follows:
359
Peter Stuge450b23f2009-04-14 00:01:34 +0000360struct cbfs_payload {
361 struct cbfs_payload_segment segments;
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000362}
363
364The header contains a number of segments corresponding to the segments
365that need to be loaded for the payload.
366
367The following is the structure of each segment header:
368
Peter Stuge450b23f2009-04-14 00:01:34 +0000369struct cbfs_payload_segment {
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000370 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
380PAYLOAD_SEGMENT_CODE 0x45444F43 The segment contains executable code
381PAYLOAD_SEGMENT_DATA 0x41544144 The segment contains data
382PAYLOAD_SEGMENT_BSS 0x20535342 The memory speicfied by the segment
383 should be zeroed
384PAYLOAD_SEGMENT_PARAMS 0x41524150 The segment contains information for
385 the payload
386PAYLOAD_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
390be independently compressed. There are three compression types defined by
Patrick Georgi2f39eae2013-08-31 08:16:27 +0200391this version of the standard: none (0x0), lzma (0x1), and nrv2b
392(0x02, deprecated), though additional types may be added assuming that
393coreboot understands how to handle the scheme.
Stefan Reinauer013c7cf2009-04-08 07:47:01 +0000394
395'offset' is the address of the data within the component, starting from
396the component header.
397
398'load_addr' is a 64 bit value indicating where the segment should be placed
399in memory.
400
401'len' is a 32 bit value indicating the size of the segment within the
402component.
403
404'mem_len' is the size of the data when it is placed into memory.
405
406The data will located immediately following the last segment.
407
408=== Option ROMS ===
409
410The third specified component type will be Option ROMs. Option ROMS will
411have component type '0x30'. They will have no additional header, the
412uncompressed binary data will be located in the data portion of the
413component.
414
415=== NULL ===
416
417There is a 4th component type ,defined as NULL (0xFFFFFFFF). This is
418the "don't care" component type. This can be used when the component
419type is not necessary (such as when the name of the component is unique.
420i.e. option_table). It is recommended that all components be assigned a
421unique type, but NULL can be used when the type does not matter.