| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| # coreboot architecture | ||
|
|
||
| ## Overwiew | ||
| ![][architecture] | ||
|
|
||
| [architecture]: comparision_coreboot_uefi.svg | ||
|
|
||
| ## Stages | ||
| coreboot consists of multiple stages that are compiled as separate binaries and | ||
| are inserted into the CBFS with custom compression. The bootblock usually doesn't | ||
| have compression while the ramstage and payload are compressed with LZMA. | ||
|
|
||
| Each stage loads the next stage a given address (possibly decompressing it). | ||
|
|
||
| Some stages are relocatable and can be placed anywhere in DRAM. Those stages are | ||
| usually cached in CBMEM for faster loading times on ACPI S3 resume. | ||
|
|
||
| Supported stage compressions: | ||
| * none | ||
| * LZ4 | ||
| * LZMA | ||
|
|
||
| ## bootblock | ||
| The bootblock is the first stage executed after CPU reset. It is written in | ||
| assembly language and its main task is to set up everything for a C-environment: | ||
|
|
||
| Common tasks: | ||
|
|
||
| * Cache-As-RAM for heap and stack | ||
| * Set stack pointer | ||
| * Clear memory for BSS | ||
| * Decompress and load the next stage | ||
|
|
||
| On x86 platforms that includes: | ||
|
|
||
| * Microcode updates | ||
| * Timer init | ||
| * Switching from 16-bit real-mode to 32-bit protected mode | ||
|
|
||
| The bootblock loads the romstage or the verstage if verified boot is enabled. | ||
|
|
||
| ### Cache-As-Ram | ||
| The *Cache-As-Ram*, also called Non-Eviction mode, or *CAR* allows to use the | ||
| CPU cache like regular SRAM. This is particullary usefull for high level | ||
| languages like `C`, which need RAM for heap and stack. | ||
|
|
||
| The CAR needs to be activated using vendor specific CPU instructions. | ||
|
|
||
| The following stages run when Cache-As-Ram is active: | ||
| * bootblock | ||
| * romstage | ||
| * verstage | ||
| * postcar | ||
|
|
||
| ## verstage | ||
| The verstage is where the root-of-trust starts. It's assumed that | ||
| it cannot be overwritten in-field (together with the public key) and | ||
| it starts at the very beginning of the boot process. | ||
| The verstage installs a hook to verify a file before it's loaded from | ||
| CBFS or a partition before it's accessed. | ||
|
|
||
| The verified boot mechanism allows trusted in-field firmware updates | ||
| combined with a fail-safe recovery mode. | ||
|
|
||
| ## romstage | ||
| The romstage initializes the DRAM and prepares everything for device init. | ||
|
|
||
| Common tasks: | ||
|
|
||
| * Early device init | ||
| * DRAM init | ||
|
|
||
| ## postcar | ||
| To leave the CAR setup and run code from regular DRAM the postcar-stage tears | ||
| down CAR and loads the ramstage. Compared to other stages it's minimal in size. | ||
|
|
||
| ## ramstage | ||
|
|
||
| The ramstage does the main device init: | ||
|
|
||
| * PCI device init | ||
| * On-chip device init | ||
| * TPM init (if not done by verstage) | ||
| * Graphics init (optional) | ||
| * CPU init (like set up SMM) | ||
|
|
||
| After initialization tables are written to inform the payload or operating system | ||
| about the current hardware existance and state. That includes: | ||
|
|
||
| * ACPI tables (x86 specific) | ||
| * SMBIOS tables (x86 specific) | ||
| * coreboot tables | ||
| * devicetree updates (ARM specific) | ||
|
|
||
| It also does hardware and firmware lockdown: | ||
| * Write-protection of boot media | ||
| * Lock security related registers | ||
| * Lock SMM mode (x86 specific) | ||
|
|
||
| ## payload | ||
| The payload is the software that is run after coreboot is done. It resides in | ||
| the CBFS and there's no possibility to choose it at runtime. | ||
|
|
||
| For more details have a look at [payloads](../payloads.md). | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,153 @@ | ||
| # Flashmap and Flashmap Descriptor in coreboot | ||
|
|
||
| ## Flashmap | ||
|
|
||
| [Flashmap](https://code.google.com/p/flashmap) (FMAP) is a binary format to | ||
| describe partitions in a flash chip. It was added to coreboot to support the | ||
| requirements of Chromium OS firmware but then was also used in other scenarios | ||
| where precise placement of data in flash was necessary, or for data that is | ||
| written to at runtime, as CBFS is considered too fragile for such situations. | ||
| The Flashmap implementation inside coreboot is the de facto standard today. | ||
|
|
||
| Flashmap partitions the image into clearly delimited sections and some of those | ||
| sections may be CBFSes that can hold arbitrary-length files (at least one, the | ||
| default CBFS, called `COREBOOT`). General guidance is that everything with | ||
| strict layout requirements (e.g. must be aligned to erase blocks or | ||
| something else) should have its own Flashmap section, and everything else should | ||
| normally go into CBFS. | ||
|
|
||
| The Flashmap itself starts with a header `struct fmap` and followed by a list of | ||
| section descriptions in `strcut fmap_area`. | ||
|
|
||
| ### Header | ||
| The header `struct fmap` has following fields: | ||
| * `signature`: 8 characters as `"__FMAP__"`. | ||
| * `ver_major`: one byte for major version (currently only 1). | ||
| * `ver_minor`: one byte for minor version (current value is 1). | ||
| * `base`: 64 bit integer for the address of the firmware binary. | ||
| * `size`: 32 bit integer for the size of firmware binary in bytes. | ||
| * `name`: 32 characters for the name of the firmware binary. | ||
| * `nareas`: 16 bit integer for the number of area definitions (i.e., how many | ||
| sections are in this firmware image) following the header. | ||
|
|
||
| ### Area Definition | ||
| The section is defined by `struct fmap_area` with following fields: | ||
| * `offset`: 32 bit integer for where the area starts (relative to `base` in | ||
| header). | ||
| * `size`: 32 bit integer for the size of area in bytes. | ||
| * `name`: 32 characters for a descriptive name of this area. Should be unique to | ||
| all sections inside same Flashmap. | ||
| * `flags`: 16 bit integer for attributes of this area (see below). | ||
|
|
||
| ### Area Flags | ||
| Currently the defined values for `flags` in `struct fmap_area` are: | ||
| * `FMAP_AREA_PRESERVE`: suggesting the section should be preserved when | ||
| updating firmware, usually for product data like serial number, MAC address, | ||
| or calibration and cache data. | ||
| * `FMAP_AREA_STATIC`: Not really used today. | ||
| * `FMAP_AREA_COMPRESSED`: Not really used today. | ||
| * `FMAP_AREA_RO`: Not really used today. | ||
|
|
||
| ### FMAP section | ||
| The whole Flashmap (`struct fmap` and list of `struct fmap_area`) should be | ||
| stored in a standalone section named as `FMAP` (which should be also described | ||
| by the Flashmap itself in `struct fmap_area`). There's no restriction for where | ||
| it should be located (or how large), but usually we need to do a linear or | ||
| binary search on whole firmware binary image to find Flashmap so a properly | ||
| aligned address would be better. | ||
|
|
||
| ### COREBOOT section | ||
| coreboot firmware images (`coreboot.rom`) should have at least one Flashmap | ||
| section that is reserved for CBFS. Usually it is named as `COREBOOT`. | ||
|
|
||
| ## Flashmap Descriptor | ||
|
|
||
| Since coreboot is starting to use a "partition" of Flashmap to describe the | ||
| flash chip layout (both at runtime and when flashing a new image onto a | ||
| chip), the project needs a reasonably expressive plain text format for | ||
| representing such sections in the source tree. | ||
|
|
||
| Flashmap Descriptor (FMD) is a [language and | ||
| compiler](https://chromium-review.googlesource.com/#/c/255031) inside coreboot | ||
| utility folder that can be used to generate final firmware images (i.e. | ||
| `coreboot.rom`) formatted by Flashmap. | ||
|
|
||
| The FMD implementation is in coreboot `utils/cbfstool` folder. Here's an | ||
| informal language description: | ||
|
|
||
| ``` | ||
| # <line comment> | ||
| <image name>[@<memory-mapped address>] <image size> { | ||
| <section name>[(flags)][@<offset from start of image>] [<section size>] [{ | ||
| <subsection name>[@<offset from start of parent section>] [<subsection size>] [{ | ||
| # Sections can be nested as deeply as desired | ||
| <subsubsection name>[(flags)][@...] [...] [{...}] | ||
| }] | ||
| [<subsection name>[(flags)][@...] [...] [{...}]] | ||
| # There can be many subsections at each level of nesting: they will be inserted | ||
| # sequentially, and although gaps are allowed, any provided offsets are always | ||
| # relative to the closest parent node's and must be strictly increasing with neither | ||
| # overlapping nor degenerate-size sections. | ||
| }] | ||
| } | ||
| ``` | ||
|
|
||
| Note that the above example contains a few symbols that are actually meta | ||
| syntax, and therefore have neither meaning nor place in a real file. The `<.*>`s | ||
| indicate placeholders for parameters: | ||
|
|
||
| * The names are strings, which are provided as single-word (no white space) | ||
| groups of syntactically unimportant symbols (i.e. every thing except `@`, `{`, | ||
| and `}`): they are not surrounded by quotes or any other form of delimiter. | ||
| * The other fields are non-negative integers, which may be given as decimal or | ||
| hexadecimal; in either case, a `K`, `M`, or `G` may be appended (without | ||
| intermediate white space) as a multiplier. | ||
| * Comments consist of anything one manages to enter, provided it doesn't start a | ||
| new line. | ||
|
|
||
| The `[.*]`s indicate that a portion of the file could be omitted altogether: | ||
|
|
||
| * Just because something is noted as optional doesn't mean it is in every case: | ||
| the answer might actually depend on which other information is---or | ||
| isn't---provided. | ||
| * The "flag" specifies the attribute or type for given section. The most | ||
| important supported flag is "CBFS", which indicates the section will contain | ||
| a CBFS structure. | ||
| * In particular, it is only legal to place a (CBFS) flag on a leaf section; that | ||
| is, choosing to add child sections excludes the possibility of putting a CBFS | ||
| in their parent. Such flags are only used to decide where CBFS empty file | ||
| headers should be created, and do not result in the storage of any additional | ||
| metadata in the resulting FMAP section. | ||
|
|
||
| Additionally, it's important to note these properties of the overall file and | ||
| its values: | ||
|
|
||
| * Other than within would-be strings and numbers, white space is ignored. It | ||
| goes without saying that such power comes with responsibility, which is why | ||
| this sentence is here. | ||
| * Although the `section name` must be globally unique, one of them may (but is | ||
| not required to) match the image name. | ||
| * It is a syntax error to supply a number (besides 0) that begins with the | ||
| character `0`, as there is no intention of adding octals to the mix. | ||
| * The image's memory address should be present on (and only on) layouts for | ||
| memory-mapped chips. | ||
| * Although it may be evident from above, all `section` offsets are relative only | ||
| to the immediate parent. There is no way to include an absolute offset (i.e. | ||
| from the beginning of flash), which means that it is "safe" to reorder the | ||
| sections within a particular level of nesting, as long as the change doesn't | ||
| cause their positions and sizes to necessitate overlap or zero sizes. | ||
| * A `section` with omitted offset is assumed to start at as low a position as | ||
| possible (with no consideration of alignment) and one with omitted size is | ||
| assumed to fill the remaining space until the next sibling or before the end | ||
| of its parent. | ||
| * It's fine to omit any `section`'s offset, size, or both, provided its position | ||
| and size are still unambiguous in the context of its *sibling* sections and | ||
| its parent's *size*. In particular, knowledge of one .*section 's children or | ||
| the `section`s' common parent's siblings will not be used for this purpose. | ||
| * Although `section`s are not required to have children, the flash chip as a | ||
| whole must have at least one. | ||
| * Though the braces after `section`s may be omitted for those that have no | ||
| children, if they are present, they must contain at least one child. | ||
|
|
||
| To see the formal description of the language, please refer to the Lex and Yacc | ||
| files: `fmd_scanner.l` and `fmd_scanner.y`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # Library-specific documentation | ||
|
|
||
| This section contains documentation about coreboot internal technical | ||
| information and libraries. | ||
|
|
||
| ## Structure and layout | ||
| - [Flashmap and Flashmap Descriptor](flashmap.md) | ||
| - [ABI data consumption](abi-data-consumption.md) | ||
| - [Timestamps](timestamp.md) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # Lenovo mainboard codenames | ||
|
|
||
| ```eval_rst | ||
| .. csv-table:: | ||
| :header: "Marketing name", "Development codename" | ||
| :file: codenames.csv | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| # MSI MS-7707 V1.1 | ||
|
|
||
| * MSI MS-7707 V1.1 (Medion OEM Akoya P4385D MSN10014555) | ||
| * SandyBridge Intel P67 (BD82x6x) | ||
| * Winbond 25Q32BV (4MB) | ||
| * Fintek F71808A SuperIO | ||
| * Intel 82579V Gigabit | ||
| * NEC uPD720200 USB 3.0 Host Controller | ||
| * IME 7.0.4.1197 | ||
|
|
||
| ## Flash chip (Winbond 25Q32BV) | ||
| ```eval_rst | ||
| +---------------------+--------------------+ | ||
| | Type | Value | | ||
| +=====================+====================+ | ||
| | Size | 4 MiB | | ||
| +---------------------+--------------------+ | ||
| | BIOS range | 2 MiB | | ||
| +---------------------+--------------------+ | ||
| | Write protection | Yes (via jumper) | | ||
| +---------------------+--------------------+ | ||
| | Header | Yes (JSPI1) | | ||
| +---------------------+--------------------+ | ||
| | Package | SOIC-8 | | ||
| +---------------------+--------------------+ | ||
| | In circuit flashing | Yes | | ||
| +---------------------+--------------------+ | ||
| | Internal flashing | Yes | | ||
| +---------------------+--------------------+ | ||
| | Socketed flash | No | | ||
| +---------------------+--------------------+ | ||
| | Dual BIOS feature | No | | ||
| +---------------------+--------------------+ | ||
| | ME removable | Yes | | ||
| +---------------------+--------------------+ | ||
| ``` | ||
|
|
||
| ## Installation instructions | ||
| * The standard method is to only flash the 2MiB BIOS region. In that case it's | ||
| not needed to extract blobs from vendor firmware and internal flashing is | ||
| sufficient. | ||
| * To flash the whole chip (e.g. to disable ME) blobs are needed to build | ||
| coreboot. Blobs can be extracted with util/ifdtool from 4MiB full dump image | ||
| (see below). Its recommended to include the VGA BIOS as well (4MiB write only). | ||
| Kconfig is prepared already if it gets enabled (path and 8086,0102). | ||
| ``` | ||
| coreboot/3rdparty/blobs/mainboard/msi/ms7707 | ||
| ├── descriptor.bin | ||
| ├── gbe.bin | ||
| ├── me.bin | ||
| └── vgabios.bin | ||
| ``` | ||
| * Never write a full 4MiB image if blobs are not included. The generated | ||
| coreboot.rom file is always 4MiB but the 2MiB flash command below will only | ||
| flash the last 2MiB (BIOS) block. | ||
| * The J1-Jumper sets the 'Flash Descriptor Override Strap-Pin' and enables | ||
| full 4MiB access for internal flasher (read and write). | ||
| * **Write BIOS-range** (2MiB) with J1-Jumper=off (as on picture/default | ||
| position): | ||
| ``` | ||
| flashrom -p internal:ich_spi_force=yes --noverify-all --ifd -i bios -w coreboot.rom | ||
| ``` | ||
| * **Read full dump** (4MiB) with J1-jumper=on: | ||
| ``` | ||
| flashrom -p internal -r original.rom | ||
| ``` | ||
| * **Write full dump** (4MiB) with J1-Jumper=on: | ||
| ``` | ||
| flashrom -p internal -w coreboot.rom | ||
| ``` | ||
| * After successful flashing turn main power off, wait some seconds to drain | ||
| the capacitors, pull the battery and set the JBAT (clrcmos) jumper for some | ||
| seconds. Setting the jumper alone is not enough (the Fintek is VBAT backed). | ||
| Put all back in place and restart the board. It might need 1-2 AC power cycles | ||
| to reinitialize (running at full fan speed - don't panic). | ||
| * External flashing has been tested with RPi2 without main power connected. | ||
| 3.3V provided by RPi2. Read more about flashing methods [here](https://doc.coreboot.org/flash_tutorial/index.html). | ||
| * In case of going back to proprietary BIOS create/save cmos settings as early | ||
| as possible (do not leave BIOS on first start without saving settings). | ||
| The BIOS might corrupt nvram (not cmos!) and leave the system in a dead state | ||
| that needs an external flasher to revive. If stuck, reset the Fintek (see | ||
| above) and restart the system several times and/or try setting J1 to | ||
| temporarily disable ME. | ||
|
|
||
|  | ||
|
|
||
| * The JSPI1 header (5Ă—2 2.0mm pitch pin header) for external flashing is | ||
| directly connected to the flash chip. Additional 3.3V to /HOLD and /WP is not | ||
| needed (internally re-routed already). | ||
|
|
||
|  | ||
|
|
||
|  | ||
|
|
||
|  | ||
|
|
||
| ## Flash layout | ||
|
|
||
| * The 4MiB flashrom is divided into 4 sections: | ||
|
|
||
| ![][flashlayout] | ||
|
|
||
| ## Links | ||
|
|
||
| - [BIOS ROM] | ||
| - [Fintek F71808A datasheet] | ||
| - [Winbond 25Q32BV datasheet] | ||
|
|
||
| [BIOS ROM]: https://www.medion.com/de/servicebackend/_lightbox/treiber_details.php?did=9744 | ||
| [Winbond 25Q32BV datasheet]: https://www.winbond.com/resource-files/w25q32bv_revi_100413_wo_automotive.pdf | ||
| [Fintek F71808A datasheet]: https://www.alldatasheet.com/datasheet-pdf/pdf/459069/FINTEK/F71808A.html | ||
| [flashlayout]: flashlayout.svg |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,324 @@ | ||
| # vboot - Verified Boot Support | ||
|
|
||
| Google's verified boot support consists of: | ||
|
|
||
| * A root of trust | ||
| * Special firmware layout | ||
| * Firmware verification | ||
| * Firmware measurements | ||
| * A firmware update mechanism | ||
| * Specific build flags | ||
| * Signing the coreboot image | ||
|
|
||
| Google's vboot verifies the firmware and places measurements within the TPM. | ||
|
|
||
| *** | ||
|
|
||
| ## Root of Trust | ||
|
|
||
| When using vboot, the root-of-trust is basically the read-only portion of the | ||
| SPI flash. The following items factor into the trust equation: | ||
|
|
||
| * The GCC compiler must reliably translate the code into machine code | ||
| without inserting any additional code (virus, backdoor, etc.) | ||
| * The CPU must reliably execute the reset sequence and instructions as | ||
| documented by the CPU manufacturer. | ||
| * The SPI flash must provide only the code programmed into it to the CPU | ||
| without providing any alternative reset vector or code sequence. | ||
| * The SPI flash must honor the write-protect input and protect the specified | ||
| portion of the SPI flash from all erase and write accesses. | ||
|
|
||
| The firmware is typically protected using the write-protect pin on the SPI | ||
| flash part and setting some of the write-protect bits in the status register | ||
| during manufacturing. The protected area is platform specific and for x86 | ||
| platforms is typically 1/4th of the SPI flash part size. | ||
| Because this portion of the SPI flash is hardware write protected, it is not | ||
| possible to update this portion of the SPI flash in the field, without altering | ||
| the system to eliminate the ground connection to the SPI flash write-protect pin. | ||
| Without hardware modifications, this portion of the SPI flash maintains the | ||
| manufactured state during the system's lifetime. | ||
|
|
||
| *** | ||
|
|
||
| ## Firmware Layout | ||
|
|
||
| Several sections are added to the firmware layout to support vboot: | ||
|
|
||
| * Read-only section | ||
| * Google Binary Blob (GBB) area | ||
| * Read/write section A | ||
| * Read/write section B | ||
|
|
||
| The following sections describe the various portions of the flash layout. | ||
|
|
||
| ### Read-Only Section | ||
|
|
||
| The read-only section contains a coreboot file system (CBFS) that contains all | ||
| of the boot firmware necessary to perform recovery for the system. This firmware | ||
| is typically protected using the write-protect pin on the SPI flash part and | ||
| setting some of the write-protect bits in the status register during | ||
| manufacturing. | ||
| The protected area is typically 1/4th of the SPI flash part size and must cover | ||
| the entire read-only section which consists of: | ||
|
|
||
| * Vital Product Data (VPD) area | ||
| * Firmware ID area | ||
| * Google Binary Blob (GBB) area | ||
| * coreboot file system containing read-only recovery firmware | ||
|
|
||
| ### Google Binary Blob (GBB) Area | ||
|
|
||
| The GBB area is part of the read-only section. This area contains a 4096 or 8192 | ||
| bit public root RSA key that is used to verify the *VBLOCK* area to obtain the | ||
| firmware signing key. | ||
|
|
||
| ### Recovery Firmware | ||
|
|
||
| The recovery firmware is contained within a coreboot file system and consists of: | ||
|
|
||
| * reset vector | ||
| * bootblock | ||
| * verstage | ||
| * romstage | ||
| * postcar | ||
| * ramstage | ||
| * payload | ||
| * flash map file | ||
| * config file | ||
| * processor specific files: | ||
| * Microcode | ||
| * fspm.bin | ||
| * fsps.bin | ||
|
|
||
| The recovery firmware is written during manufacturing and typically contains | ||
| code to write the storage device (eMMC device or hard disk). The recovery image | ||
| is usually contained on a socketed device such as a USB flash drive or an | ||
| SD card. Depending upon the payload firmware doing the recovery, it may be | ||
| possible for the user to interact with the system to specify the recovery | ||
| image path. Part of the recovery is also to write the A and B areas of the SPI | ||
| flash device to boot the system. | ||
|
|
||
| ### Read/Write Section | ||
|
|
||
| The read/write sections contain an area which contains the firmware signing | ||
| key and signature and an area containing a coreboot file system with a subset | ||
| of the firmware. The firmware files in *FW_MAIN_A* and *FW_MAIN_B* are: | ||
|
|
||
| * romstage | ||
| * postcar | ||
| * ramstage | ||
| * payload | ||
| * config file | ||
| * processor specific files: | ||
| * Microcode | ||
| * fspm.bin | ||
| * fsps.bin | ||
|
|
||
| The firmware subset enables most issues to be fixed in the field with firmware | ||
| updates. The firmware files handle memory and most of silicon initialization. | ||
| These files also produce the tables which get passed to the operating system. | ||
|
|
||
| *** | ||
|
|
||
| ## Firmware Updates | ||
|
|
||
| The read/write sections exist in one of three states: | ||
|
|
||
| * Invalid | ||
| * Ready to boot | ||
| * Successfully booted | ||
|
|
||
|
|
||
| Firmware updates are handled by the operating system by writing any read/write | ||
| section that is not in the "successfully booted" state. Upon the next reboot, | ||
| vboot determines the section to boot. If it finds one in the "ready to boot" | ||
| state then it attempts to boot using that section. If the boot fails then | ||
| vboot marks the section as invalid and attempts to fall back to a read/write | ||
| section in the "successfully booted" state. If vboot is not able to find a | ||
| section in the "successfully booted" state then vboot enters recovery mode. | ||
|
|
||
| Only the operating system is able to transition a section from the | ||
| "ready to boot" state to the "successfully booted" state. | ||
| The transition is typically done after the operating system has been running | ||
| for a while indicating that successful boot was possible and the operating | ||
| system is stable. | ||
|
|
||
| Note that as long as the SPI write protection is in place then the system | ||
| is always recoverable. If the flash update fails then the system will continue | ||
| to boot using the previous read/write area. The same is true if coreboot passes | ||
| control to the payload or the operating system and then the boot fails. In the | ||
| worst case, the SPI flash gets totally corrupted in which case vboot fails the | ||
| signature checks and enters recovery mode. There are no times where the SPI | ||
| flash is exposed and the reset vector or part of the recovery firmware gets | ||
| corrupted. | ||
|
|
||
| *** | ||
|
|
||
| ## Build Flags | ||
|
|
||
| The following *Kconfig* values need to be selected to enable vboot: | ||
|
|
||
| * COLLECT_TIMESTAMPS | ||
| * VBOOT | ||
|
|
||
| The starting stage needs to be specified by selecting either | ||
| VBOOT_STARTS_IN_BOOTBLOCK or VBOOT_STARTS_IN_ROMSTAGE. | ||
|
|
||
| If vboot starts in bootblock then vboot may be built as a separate stage by | ||
| selecting `VBOOT_SEPARATE_VERSTAGE`. Additionally, if static RAM is too small | ||
| to fit both verstage and romstage then selecting `VBOOT_RETURN_FROM_VERSTAGE` | ||
| enables bootblock to reuse the RAM occupied by verstage for romstage. | ||
|
|
||
| Non-volatile flash is needed for vboot operation. This flash area may be in | ||
| CMOS, the EC, or in a read/write area of the SPI flash device. | ||
| Select one of the following: | ||
|
|
||
| * `VBOOT_VBNV_CMOS` | ||
| * `VBOOT_VBNV_EC` | ||
| * `VBOOT_VBNV_FLASH` | ||
|
|
||
| More non-volatile storage features may be found in `security/vboot/Kconfig`. | ||
|
|
||
| A TPM is also required for vboot operation. | ||
| TPMs are available in `drivers/i2c/tpm` and `drivers/pc80/tpm`. | ||
|
|
||
| In addition to adding the coreboot files into the read-only region, | ||
| enabling vboot causes the build script to add the read/write files into | ||
| coreboot file systems in *FW_MAIN_A* and *FW_MAIN_B*. | ||
|
|
||
| *** | ||
|
|
||
| ## Signing the coreboot Image | ||
|
|
||
| The following command script is an example of how to sign the coreboot image | ||
| file. This script is used on the Intel Galileo board and creates the *GBB* area | ||
| and inserts it into the coreboot image. It also updates the *VBLOCK* areas with | ||
| the firmware signing key and the signature for the *FW_MAIN* firmware. | ||
| More details are available in `3rdparty/vboot/README`. | ||
|
|
||
| ```bash | ||
| #!/bin/sh | ||
| # | ||
| # The necessary tools were built and installed using the following commands: | ||
| # | ||
| # pushd 3rdparty/vboot | ||
| # make | ||
| # sudo make install | ||
| # popd | ||
| # | ||
| # The keys were made using the following command | ||
| # | ||
| # 3rdparty/vboot/scripts/keygeneration/create_new_keys.sh \ | ||
| # --4k --4k-root --output $PWD/keys | ||
| # | ||
| # | ||
| # The "magic" numbers below are derived from the GBB section in | ||
| # src/mainboard/intel/galileo/vboot.fmd. | ||
| # | ||
| # GBB Header Size: 0x80 | ||
| # GBB Offset: 0x611000, 4KiB block number: 1553 (0x611) | ||
| # GBB Length: 0x7f000, 4KiB blocks: 127 (0x7f) | ||
| # COREBOOT Offset: 0x690000, 4KiB block number: 1680 (0x690) | ||
| # COREBOOT Length: 0x170000, 4KiB blocks: 368 (0x170) | ||
| # | ||
| # 0x7f000 (GBB Length) = 0x80 + 0x100 + 0x1000 + 0x7ce80 + 0x1000 | ||
| # | ||
| # Create the GBB area blob | ||
| # Parameters: hwid_size,rootkey_size,bmpfv_size,recoverykey_size | ||
| # | ||
| gbb_utility -c 0x100,0x1000,0x7ce80,0x1000 gbb.blob | ||
|
|
||
| # | ||
| # Copy from the start of the flash to the GBB region into the signed flash | ||
| # image. | ||
| # | ||
| # 1553 * 4096 = 0x611 * 0x1000 = 0x611000, size of area before GBB | ||
| # | ||
| dd conv=fdatasync ibs=4096 obs=4096 count=1553 \ | ||
| if=build/coreboot.rom of=build/coreboot.signed.rom | ||
|
|
||
| # | ||
| # Append the empty GBB area to the coreboot.rom image. | ||
| # | ||
| # 1553 * 4096 = 0x611 * 0x1000 = 0x611000, offset to GBB | ||
| # | ||
| dd conv=fdatasync obs=4096 obs=4096 seek=1553 if=gbb.blob \ | ||
| of=build/coreboot.signed.rom | ||
|
|
||
| # | ||
| # Append the rest of the read-only region into the signed flash image. | ||
| # | ||
| # 1680 * 4096 = 0x690 * 0x1000 = 0x690000, offset to COREBOOT area | ||
| # 368 * 4096 = 0x170 * 0x1000 = 0x170000, length of COREBOOT area | ||
| # | ||
| dd conv=fdatasync ibs=4096 obs=4096 skip=1680 seek=1680 count=368 \ | ||
| if=build/coreboot.rom of=build/coreboot.signed.rom | ||
|
|
||
| # | ||
| # Insert the HWID and public root and recovery RSA keys into the GBB area. | ||
| # | ||
| gbb_utility \ | ||
| --set --hwid='Galileo' \ | ||
| -r $PWD/keys/recovery_key.vbpubk \ | ||
| -k $PWD/keys/root_key.vbpubk \ | ||
| build/coreboot.signed.rom | ||
|
|
||
| # | ||
| # Sign the read/write firmware areas with the private signing key and update | ||
| # the VBLOCK_A and VBLOCK_B regions. | ||
| # | ||
| 3rdparty/vboot/scripts/image_signing/sign_firmware.sh \ | ||
| build/coreboot.signed.rom \ | ||
| $PWD/keys \ | ||
| build/coreboot.signed.rom | ||
| ``` | ||
|
|
||
| *** | ||
|
|
||
| ## Boot Flow | ||
|
|
||
| The reset vector exist in the read-only area and points to the bootblock | ||
| entry point. The only copy of the bootblock exists in the read-only area | ||
| of the SPI flash. Verstage may be part of the bootblock or a separate stage. | ||
| If separate then the bootblock loads verstage from the read-only area and | ||
| transfers control to it. | ||
|
|
||
| Upon first boot, verstage attempts to verify the read/write section A. | ||
| It gets the public root key from the GBB area and uses that to verify the | ||
| *VBLOCK* area in read-write section A. If the *VBLOCK* area is valid then it | ||
| extracts the firmware signing key (1024-8192 bits) and uses that to verify | ||
| the *FW_MAIN_A* area of read/write section A. If the verification is successful | ||
| then verstage instructs coreboot to use the coreboot file system in read/write | ||
| section A for the contents of the remaining boot firmware (romstage, postcar, | ||
| ramstage and the payload). | ||
|
|
||
| If verification fails for the read/write area and the other read/write area is | ||
| not valid vboot falls back to the read-only area to boot into system recovery. | ||
|
|
||
| *** | ||
|
|
||
| ## Chromebook Special Features | ||
|
|
||
| Google's Chromebooks have some special features: | ||
|
|
||
| * Developer mode | ||
| * Write-protect screw | ||
|
|
||
| ### Developer Mode | ||
|
|
||
| Developer mode allows the user to use coreboot to boot another operating system. | ||
| This may be a another (beta) version of Chrome OS, or another flavor of | ||
| GNU/Linux. Use of developer mode does not void the system warranty. Upon entry | ||
| into developer mode, all locally saved data on the system is lost. | ||
| This prevents someone from entering developer mode to subvert the system | ||
| security to access files on the local system or cloud. | ||
|
|
||
| ### Write Protect Screw | ||
|
|
||
| Chromebooks have a write-protect screw which provides the ground to the | ||
| write-protect pin of the SPI flash. | ||
| Google specifically did this to allow the manufacturing line and advanced | ||
| developers to re-write the entire SPI flash part. Once the screw is removed, | ||
| any firmware may be placed on the device. | ||
| However, accessing this screw requires opening the case and voids the | ||
| system warranty! |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # Intel Firmware Interface Table | ||
|
|
||
| The FIT allows to run code before the actual IA32 reset vector is executed | ||
| by the CPU. The FIT resides in the BIOS region (usually near the reset vector) | ||
| and is pointed to by the FIT pointer residing at `0xFFFFFFC0`. | ||
|
|
||
| ## Table layout | ||
| The table consists of blocks each 16 bytes in size. | ||
| The first is called *FIT header* the other are called *FIT entry*. | ||
|
|
||
| ![FIT in x86 memory map][fit] | ||
|
|
||
| [fit]: fit.svg | ||
|
|
||
| ## Fit types | ||
|
|
||
| Each entry has a *type* that give the other bits in the entry a different | ||
| meaning. The following types are known: | ||
|
|
||
| ```eval_rst | ||
| +-----------+------------------------------------------------------------------+ | ||
| | no. | Description | | ||
| +===========+==================================================================+ | ||
| | 0x0 | HEADER. | | ||
| +-----------+------------------------------------------------------------------+ | ||
| | 0x1 | MICROCODE. | | ||
| +-----------+------------------------------------------------------------------+ | ||
| | 0x2 | STARTUP_ACM. | | ||
| +-----------+------------------------------------------------------------------+ | ||
| | 0x7 | BIOS_STARTUP_MODULE. | | ||
| +-----------+------------------------------------------------------------------+ | ||
| | 0x8 | TPM_POLICY. | | ||
| +-----------+------------------------------------------------------------------+ | ||
| | 0x9 | BIOS_POLICY. | | ||
| +-----------+------------------------------------------------------------------+ | ||
| | 0xa | TXT_POLICY. | | ||
| +-----------+------------------------------------------------------------------+ | ||
| | 0xb | KEY_MANIFEST. | | ||
| +-----------+------------------------------------------------------------------+ | ||
| | 0xc | BOOT_POLICY_MANIFEST. | | ||
| +-----------+------------------------------------------------------------------+ | ||
| | 0x10 | CSE_SECURE_BOOT. | | ||
| +-----------+------------------------------------------------------------------+ | ||
| | 0x2d | TXTSX_POLICY. | | ||
| +-----------+------------------------------------------------------------------+ | ||
| | 0x2f | JMP_DEBUG_POLICY. | | ||
| +-----------+------------------------------------------------------------------+ | ||
| | 0x7f | SKIP. | | ||
| +-----------+------------------------------------------------------------------+ | ||
| ``` | ||
|
|
||
| ## Usage in coreboot | ||
|
|
||
| The most common usage of FIT is to use *Type1* to update microcode before | ||
| execution of the IA32 reset vector happens. | ||
|
|
||
| ## References | ||
|
|
||
| * [Intel TXT LAB handout](https://downloadmirror.intel.com/18931/eng/Intel%20TXT%20LAB%20Handout.pdf) | ||
| * [FIT bios specification](https://www.intel.com/content/dam/www/public/us/en/documents/guides/fit-bios-specification.pdf) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| CONFIG_VENDOR_LENOVO=y | ||
| CONFIG_BOARD_LENOVO_X220=y | ||
| # CONFIG_USE_NATIVE_RAMINIT is not set |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,7 +9,7 @@ choice | |
| default UBOOT_STABLE | ||
|
|
||
| config UBOOT_STABLE | ||
| bool "v2019.4" | ||
| help | ||
| Stable U-Boot version | ||
|
|
||
|
|
||