Coreboot Boot Structure LA-UR-06-7928
Total Page:16
File Type:pdf, Size:1020Kb
coreboot boot structure LA-UR-06-7928 New coreboot group March 13, 2008 Abstract This is the new coreboot boot architecture. 1 Introduction The new coreboot boot architecture depends on CAR, with payloads appearing as files in a LAR archive. The device tree is defined by a device tree blob (DTB) and all the activities flow from that. For now, the DTC will produce a standard coreboot v2 device tree; this will, we hope, be improved. romcc is gone. Required attributes of a CPU for coreboot v3: • Supports CAR Required platform attributes: 2 Goal 2.1 Design Goals • All components are seperate modules. • The strict seperation of normal/fallback does not exist anymore. Any module can be available several times. • Commonly used code is shared. There is one implementation of printk, and one implementation for each compressor. • Under construction, things have changed recently. 2.2 Features 3 FLASH layout Shown in 1 is the layout of the whole FLASH. Note that we can kill the buildrom tool, since the FLASH code is now a LAR archive. Note that the linker script will now be very simple. The initram is roughly what is in auto.c, although the early hardware setup from auto.c is now in the pre-initram, so that we have serial output and other capabilities. The FLASH recovery is interesting: in hopeless cases, the serial port can be used to load a new flash image, and allow a successful boot from a totally hosed machine. VPD includes data such as the MAC address, instance of the motherboard, etc. The DTB can be modified by the flashrom tool, and hence a platform can be customized from a binary FLASH image. Each LAR file has a checksum attached to the end, so that the system can verify that the data is uncorrupted. We now build at least four targets for a platform: • Basic startup and CAR (in most cases, same for all processors of a given type) • Pre-initram device setup (large FLASH, serial port, etc.) • initram • Traditional coreboot RAM code (LAR, etc.) • Load payload and start it 4 Introduction to the coreboot device tree 4.1 Purpose and function The coreboot device tree is probably the single most important concept in core- boot, and, in V2, was the least understood part of the software. The device tree provides a tremendous amount of capability to the software. The initial tree, which almost always will be an incomplete representation of the hardware (consider pluggable devices), is created by the configuration tool – in V3, the device tree compiler, or DTC. The initial tree is statically allocated at com- pile time. At runtime, hardware must be probed, and the tree must be filled in, extended, and even restructured as the hardware discovery process occurs. The restructuring mainly consists of adding nodes, and reordering nodes in the tree to accomodate these new nodes. The tree represents devices as nodes and busses as edges (called links) between the nodes. Some devices can bridge a bus to another; these are intermediate nodes in the tree. Other devices do not bridge busses; these are leaf nodes. And, of course, a bridge device might exist with nothing on the other side – this device will of course also be a leaf node. Figure 1: FLASH layout LAR archive lzma nrv2b normal/initram normal/coreboot.lzma fallback/initram fallback/coreboot.lzma memtest86/memtest86.lzma vgabios.lzma Basic startup CAR src/cpu/x86/crt0.S Pre−initram device setup Device Tree Blob Device Tree Code CPIO code support FLASH recovery from serial ROM Code Checksum (4 bytes) 0xffffff00 VPD VPD checksum (4 bytes) 0xfffffff0 JMP start At build time, the programmer can specify, via a configuration file, hardware that is likely to be on the mainboard, although it is not required to be present (e.g. a 2-cpu system might have only one CPU installed). Also, hardware that can be probed, and that does not need any special configuration, can be left out of the configuration file and left to be discovered dynamically, even if it is known to be on the board. At run time, the software must determine what hardware exists, and modify the tree to accord to reality. This modification can include deletion of nodes, including bridge nodes; and even deletion of edges in the graph. The software must also be able to add new nodes and edges, as bridges and devices are found. Finally, once the tree is built, the device tree software must allocate resources to each device. Resources, in this context, are for the most part address space ranges, in memory or I/O space. A given device will require a certain range of addresses and, still worse, might require that those addresses be fixed at a certain value (such as a superio which is hardwired to address 0x4e). The software must allocate the resources to devices, and, for a bridge, must allocate the resources to the bridge that are held by all the devices on the other side of the bridge. The process of resource allocation must take into acount the fact that ad- dresses at a bridge may have special alignment requirements (e.g. the 4096 byte alignment for memory address ranges); that memory addresses on a device must be aligned to the size of the region (e.g. a 512KiB region must be aligned to 512KiB); and other restrictions dependent on the device or bridge. Another issue is the use of subtractive address ranges, which define an address range that is picked up by default if no other resource claims it. Subtractive address ranges are typically used for legacy PC address ranges. 4.2 Device tree structures There are three primary objects which are used to manage the coreboot de- vice tree: devices, links, and drivers. Devices and links are generic structures: drivers, on the other hand, are specialized. We describe these parts, and their relationship, below. These structures are linked together in the static device tree. The static de- vice tree, a set of initialized C structures, is created by the device tree compiler, in the file build/statictree.c, using as input the dts file in the mainboard direc- tory. This tree defines the hardware that is known to exist on the mainboard. At run time, the static tree is elided with dynamically determined information, and can even be restructured to some extent (e.g., the static tree has a device at 0:4.0; if a dynamic device is found at 0:3.0, it will be placed in the tree “in front of” the 0:4.0 device). Each device has a void * which can be filled in, via the dts file, with non- generic, i.e., device-specific, information. What’s the difference between generic and non-generic information? As an example, the PCI configuration address or “path” of a device is generic; there is a path of some sort for every device in a system. But, not all devices have iden- Figure 2: The files in the i440bx directory. [rminnich@q ~]$ ls ~/src/bios/coreboot-v3/northbridge/intel/i440bxemulation/ config.h i440bx.c i440bx.h Kconfig Makefile tical capabilities. Some PCI devices have IDE controllers, others do not; some can drive the legacy PC XBUS, others can not; and so on. In coreboot V1, we attempted to create devices that were the union of all possible devices, but cre- ating such a union proved to be impossible, as new devices with new capabilities came out. So, in V2, we split off the device-specific information into a seperate structure. The generic device structure is defined in include/device/device.h; the device-specific structures are defined in the source directory for a given de- vice, always in a file named config.h, e.g. src/northbridge/intel/i440gx/config.h. For an analogous structure, see the Linux kernel Virtual File System (VFS) code. A VFS is a generic file system, with a generic structure, which can be extended via individual file system structures. More on device source directories, configuration structure and con- fig.h file The generic code for the device tree is contained in the device directory. The code for a given device is contained in a single directory, which is not shared with any other device. The naming convention is <device-type>/<vendor>/<device- name>/filename. The config.h file contains configuration information for a given device. Devices, in some cases, have special control registers that need to be set. In a few cases, generic code can handle these operations: see device/pci device.c. Device-specific functions for controlling the device and its settings are found in the device-specific directory. All the configuration variables for controlling a device must be defined in a single structure; to reiterate, that structure is defined in the file config.h. It is one structure, instead of a set of variables, because it must be instantiated and initialized by the device tree compiler (dtc), and a pointer to it is held in the generic device structure. We show an example of a specific device, below. The device is the i440bx emulation. i440bx.h contains manifest constants defining registers, bits in registers, and so on. Config.h defines the structures and declarations that allow the static device tree to compile. We show it below. The file contains an extern declaration, pointing to a set of operations for the chip (needed to get statictree.c to compile); and the chip-specific structure, containing the control variable ramsize. The Kconfig and Makefile are for the Kbuild system. Figure 3: config.h for the i440bx extern struct chip operations northbridge intel i440bxemulation ops; struct northbridge intel i440bx config { /* The various emulators don’t always get 440BX right.