#LyX 1.4.2 created this file. For more info see http://www.lyx.org/ \lyxformat 245 \begin_document \begin_header \textclass latex8 \language english \inputencoding default \fontscheme default \graphics default \paperfontsize 10 \spacing single \papersize default \use_geometry false \use_amsmath 0 \cite_engine basic \use_bibtopic false \paperorientation portrait \secnumdepth 2 \tocdepth 2 \paragraph_separation indent \defskip medskip \quotes_language english \papercolumns 1 \papersides 1 \paperpagestyle empty \tracking_changes false \output_changes true \end_header \begin_body \begin_layout Title LinuxBIOS boot structure \newline LA-UR-06-7928 \end_layout \begin_layout Author New LinuxBIOS group \newline \end_layout \begin_layout Standard \begin_inset ERT status collapsed \begin_layout Standard \backslash thispagestyle{empty} \end_layout \end_inset \end_layout \begin_layout Abstract This is the new LinuxBIOS boot architecture. \end_layout \begin_layout Section Introduction \begin_inset Note Note status collapsed \begin_layout Standard rae Sat Jun 20 18:39:35 1998 \end_layout \begin_layout Standard Section number will appear correctly on paper. \end_layout \begin_layout Standard That is, "1." instead of just "1" \end_layout \end_inset \end_layout \begin_layout Standard The new LinuxBIOS boot architecture depends on CAR, with payloads appearing as files in a CPIO 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 LinuxBIOS v2 device tree; this will, we hope, be improved. romcc is gone. \end_layout \begin_layout Standard Required attributes of a CPU for LinuxBIOS v3: \end_layout \begin_layout Itemize Supports CAR \end_layout \begin_layout Standard Required platform attributes: \end_layout \begin_layout Section Goal \end_layout \begin_layout Subsection Design Goals \end_layout \begin_layout Itemize Under construction, things have changed recently. \end_layout \begin_layout Subsection Features \end_layout \begin_layout Section FLASH layout \end_layout \begin_layout Standard Shown in \begin_inset LatexCommand \ref{fig:FLASH-layout} \end_inset is the layout of the whole FLASH. Note that we can kill the buildrom tool, since the FLASH code is now a CPIO 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 CPIO 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: \end_layout \begin_layout Itemize Basic startup and CAR (in most cases, same for all processors of a given type) \end_layout \begin_layout Itemize Pre-initram device setup (large FLASH, serial port, etc.) \end_layout \begin_layout Itemize initram \end_layout \begin_layout Itemize Traditional LinuxBIOS RAM code (LAR, etc.) \end_layout \begin_layout Itemize Load payload and start it \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Caption \begin_inset LatexCommand \label{fig:FLASH-layout} \end_inset FLASH layout \end_layout \begin_layout Standard \begin_inset Graphics filename flashlayout.eps \end_inset \end_layout \end_inset \end_layout \begin_layout Section Boot Process \end_layout \begin_layout Standard The boot process consists of a number of independent, seperately compiled components. Unlike V2, we are not using ld scripts to glue these components together, since the overall bugginess of the various tools (as and ld in particular) made use of ldscripts very hard to mainbain. \end_layout \begin_layout Standard By design, the seperate components can be individually replaced without replacing any other component. This design impliies that functions such as print are duplicated in the code. If this duplication causes problems we can revisit this decision. \end_layout \begin_layout Subsection Stage 0: Basic startup (ASM, PIC) and CAR (ASM, PIC) in arch/{architecture} \end_layout \begin_layout Standard The Stage 0 code is a binary blob that (on x86) lives in 8192 bytes at the top of memory. This code comprises a jump vector to get from reset to the start of the stage 0 code. The stage 0 code is responsible for any steps needed to make the processor behave properly, such as flushing TLBs, clearing paging bits, and so on. Stage 0, on the x86, enables segments but not paging; on other platforms, stage1 might also set up an initial page table. Stage 0 at minimum switches to a protected mode of some sort, and on x86, at minimum switches on 32-bit mode. Stage 0 then sets up Cache-As-Ram (CAR) so that stage 1 can be be written in C, and use functions. \end_layout \begin_layout Standard This code \begin_inset Quotes eld \end_inset begins life \begin_inset Quotes erd \end_inset executing in real mode, at 0xf000:fff0. The code does initial setup, transitions to 32-bit mode, and then falls into the CAR code. \end_layout \begin_layout Standard The files are named for the type of target. The current code, named stage0_i586.S, is designed for a generic i586. The file to assemble is determined from the CONFIG_STAGE0 makefile variable, which is set in the mainboard Kconfig file. Please note, there are NO code files included. The assembly code for early startup rarely changes. To give an example, much of the Stage 0 code was written in 1999/2000, and has changed little since. The CAR code has been unchanged since it was written two years ago. \end_layout \begin_layout Standard CAR is a standard cache-as-ram assembly source for the architecture. It is actually included in the stage0_*.S file; but we maintain a distinction in the stage nomenclature for now. This code sets up cache-as-ram, zeros a memory area, sets up a stack, and then calls Stage 1. \end_layout \begin_layout Subparagraph* Config variables: \end_layout \begin_layout Enumerate CONFIG_CARTEST. Test the CAR once it is enabled. \end_layout \begin_layout Enumerate CONFIG_ROMSIZE. Size of the ROM part. \end_layout \begin_layout Subsection Stage 1: C, in arch/{architecture} \end_layout \begin_layout Enumerate Preboot hardware, as from auto.c (C) \end_layout \begin_layout Enumerate Decide whether we can proceed or must recover from serial port. (C) \end_layout \begin_layout Enumerate Checksum the top flash \begin_inset Quotes eld \end_inset boot area \begin_inset Quotes erd \end_inset , if it is bad then ... recover from serial port (C, PIC). We can definitely reflash CPIO archive, but NOTE: reflashing the boot block is tricky ... (C) \end_layout \begin_layout Enumerate Examine the flash. Look in DTB option node, normal property for directory named by the boot type (e.g. 'normal', \begin_inset Quotes eld \end_inset fallback', etc.) (C) \end_layout \begin_layout Enumerate In that directory, need 'initram', 'payload.ext', and others. make sure that in '/', there is a decompressor of the right type for each extension needed. (C) \end_layout \begin_layout Subsection Stage 2: Device tree \end_layout \begin_layout Standard Run the standard device tree code. This code runs in 6 phases. \end_layout \begin_layout Subparagraph* Phase 1 \end_layout \begin_layout Standard These are any functions that are required to make printk operational. No other code should be run in Phase 1. \end_layout \begin_layout Standard Post codes: \end_layout \begin_layout Itemize Entry: 0x20 \end_layout \begin_layout Itemize Exit: 0x2f \end_layout \begin_layout Subparagraph* Phase 2 \end_layout \begin_layout Standard These are functions that are required before any PCI operations of any kind are run. \end_layout \begin_layout Subparagraph* Post codes: \end_layout \begin_layout Itemize Entry: 0x30 \end_layout \begin_layout Itemize Exit: 0x3f \end_layout \begin_layout Subparagraph* Phase 3 \end_layout \begin_layout Subparagraph* Post codes: \end_layout \begin_layout Itemize Entry: 0x40 \end_layout \begin_layout Itemize Exit: 0x4f \end_layout \begin_layout Subparagraph* Phase 4 \end_layout \begin_layout Subparagraph* Post codes: \end_layout \begin_layout Itemize Entry: 0x50 \end_layout \begin_layout Itemize Exit: 0x5f \end_layout \begin_layout Subparagraph* Phase 5 \end_layout \begin_layout Subparagraph* Post codes: \end_layout \begin_layout Itemize Entry: 0x60 \end_layout \begin_layout Itemize Exit: 0x6f \end_layout \begin_layout Subparagraph* Phase 6 \end_layout \begin_layout Standard Post codes: \end_layout \begin_layout Itemize Entry: 0x70 \end_layout \begin_layout Itemize Exit: 0x7f \end_layout \begin_layout Subsection Stage 3: elf boot \end_layout \begin_layout Quotation WARNING: you can not load any elf segment in the range 0 to 0x1000. That is our stack. \end_layout \begin_layout Enumerate Each file has a four-byte checksum at the end. Check the checksum for each one. (C) \end_layout \begin_layout Enumerate If all the tests pass, run each one, in order, decompressing those which need it. The last one might not return. If the checksum fails, If the test fails, use the backup property in the option node to find a backup. initram is (C, PIC) as it must execute in place. The LinuxBIOS payload will be uncompressed to RAM, and is in C, but need not be PIC. \end_layout \begin_layout Subsection Stage 4 \end_layout \begin_layout Section The static tree (This part needs to be updated, once the other stages are done) \end_layout \begin_layout Standard The static tree is generated from the DTS. Shown is a sample DTS, for QEMU. Note that we don't fill out all properties of each node, e.g. the northbridge. The sum total of all properties is found in the dts for that node in the source directory, i.e. src/northbridge/intel/440bx/440bx.dts (is this name ok? Or just chip.dts?) \end_layout \begin_layout Quote \begin_inset Float figure wide false sideways false status open \begin_layout Caption Sample DTS \end_layout \begin_layout LyX-Code /{ \end_layout \begin_layout LyX-Code model = "qemu"; \end_layout \begin_layout LyX-Code #address-cells = <1>; \end_layout \begin_layout LyX-Code #size-cells = <1>; \end_layout \begin_layout LyX-Code compatible = "emulation-i386,qemu"; \end_layout \begin_layout LyX-Code cpus { \end_layout \begin_layout LyX-Code #address-cells = <1>; \end_layout \begin_layout LyX-Code #size-cells = <0>; \end_layout \begin_layout LyX-Code emulation,qemu-i386@0{ \end_layout \begin_layout LyX-Code name = "emulation,qemu-i386"; \end_layout \begin_layout LyX-Code device_type = "cpu"; \end_layout \begin_layout LyX-Code clock-frequency = <5f5e1000>; \end_layout \begin_layout LyX-Code timebase-frequency = <1FCA055>; \end_layout \begin_layout LyX-Code linux,boot-cpu; \end_layout \begin_layout LyX-Code reg = <0>; \end_layout \begin_layout LyX-Code i-cache-size = <2000>; \end_layout \begin_layout LyX-Code d-cache-size = <2000>; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code memory@0 { \end_layout \begin_layout LyX-Code device_type = "memory"; \end_layout \begin_layout LyX-Code reg = <00000000 20000000>; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code /* the I/O stuff */ \end_layout \begin_layout LyX-Code northbridge,intel,440bx{ \end_layout \begin_layout LyX-Code associated-cpu = <&/cpus/emulation,qemu-i386@0>; \end_layout \begin_layout LyX-Code southbridge,intel,piix4{ \end_layout \begin_layout LyX-Code superio,nsc,sucks{ \end_layout \begin_layout LyX-Code uart@0{ \end_layout \begin_layout LyX-Code enabled=<1>; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code chosen { \end_layout \begin_layout LyX-Code bootargs = "root=/dev/sda2"; \end_layout \begin_layout LyX-Code linux,platform = <00000600>; \end_layout \begin_layout LyX-Code linux,stdout-path="/dev/ttyS0"; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code \end_layout \begin_layout LyX-Code options { \end_layout \begin_layout LyX-Code normal="normal"; \end_layout \begin_layout LyX-Code fallback="fallback"; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout LyX-Code \end_layout \end_inset \end_layout \begin_layout Standard \begin_inset Note Comment status collapsed \begin_layout Standard \begin_inset LatexCommand \bibtex[latex8]{yourbibfile} \end_inset \end_layout \end_inset \end_layout \begin_layout Subsection How DTC will compile the DTS \end_layout \begin_layout Standard There are two pieces to the static tree. The first is the tree itself. As in v2, the user does not see the structures and types that define this tree; the user does define the structure of the tree by the way they lay out the config file. Sibling, child, and parent references are defined by the use of reserved names (sibling, child, and parent, unsurprisingly) and the use of & to define what the sibling, child, and parent keywords are referring to. \end_layout \begin_layout Standard The second part of the tree is the per-chip and per-device information. As in v2, each device or chip can define a structure which defines per-device information. These structures are called config structures, and define per-instance configuration of a chip. A survey of all the v2 structures shows that for almost all such config structures, almost all use int, unsigned long and unsigned int, char, and array of char types. However, for superio parts, the config structures in almost all cases contain structure declarations. We could in theory resolve the superio issue as follows: define the superio struct as having links, much as our other structures do now: \end_layout \begin_layout LyX-Code struct superio { \end_layout \begin_layout LyX-Code void *links[8]; \end_layout \begin_layout LyX-Code }; \end_layout \begin_layout Standard Then initialize them: \end_layout \begin_layout LyX-Code struct superio superio { \end_layout \begin_layout LyX-Code .links = {&pc_keyboard, &com1, &com2, 0}; \end_layout \begin_layout LyX-Code } \end_layout \begin_layout Standard In our opinion, this is asking for trouble. We currently, in the superio code, can catch stupid errors in usage that would be lost were we to go to this \family sans void * based approach. In fact, we can argue that we ought to be adding stronger type checking to the tree, not taking it away. As of this version of the document, the handling of the superio is not defined. \end_layout \begin_layout Standard Note that we are going to need an unflatten tool to generate the device tree. The steps are as follows: \end_layout \begin_layout Itemize Compile time creation of the C structures. \end_layout \begin_layout Itemize Run-time filling in the blanks with data about real hardware. \end_layout \begin_layout Itemize Runtime generation of the OFW device tree. \end_layout \begin_layout Standard The DTS is defined per each mainboard. It uses elements which are actually defined elsewhere -- for example, if the user references the Intel 440BX northbridge, the DTC must pull in northbidg e/intel/440bx/dts to get the full set of definitions. Call the full DTS the base DTS; call the DTS mentioned in the mainboard DTS the instance DTS. Each member of the DTS from the base DTS must be initialized in some manner so we can infter type and default values. The instance can define some, all, or none of the values. The DTC will create a C file with structure declarations and initializations in it. \end_layout \begin_layout Standard We show how this looks in \end_layout \begin_layout Standard \begin_inset Float figure wide false sideways false status open \begin_layout Caption How we get from the mainboard DTS to C \end_layout \end_inset \end_layout \begin_layout Section Makefile targets \end_layout \begin_layout Subsection lzma \end_layout \begin_layout Standard This is for creating the linuxbios.lzma file. \end_layout \begin_layout Subsection initram \end_layout \begin_layout Standard This is for creating initram. The actual files used can be defined in any Makefile that is part of this build. Typically, the files are defined in the northbridge Makefile. \end_layout \begin_layout Subsection linuxbios_ram \end_layout \begin_layout Standard This is the code that runs in RAM. This is almost always hardwaremain(). This code is almost always defined by the mainboard Makefile. \end_layout \begin_layout Subsection payload \end_layout \begin_layout Standard This is what we boot. Almost always this is FILO, Etherboot, Linux kernel, Open FirmWare, and so on. \end_layout \begin_layout Subsection linuxbios.lar \end_layout \begin_layout Standard This is the \begin_inset Quotes eld \end_inset file system \begin_inset Quotes erd \end_inset that contains the lzma, initram, linuxbios_ram, and payload targets. \end_layout \begin_layout Subsection jumpvector \end_layout \begin_layout Standard This is the jumpvector. Jumpvector is entered at power on reset (POR) or hard or soft reset. \end_layout \begin_layout Subsection vpd \end_layout \begin_layout Standard This contains information that a payload can use to find out about the mainboard. \end_layout \begin_layout Section Conclusions \end_layout \begin_layout Standard This is great stuff. \end_layout \begin_layout Section Appendix A: issues \end_layout \begin_layout Itemize One issue I thought I should mention before all the tools start >> making incorrect assumptions: on most non-x86 architectures, the >> bootblock is at the start of the flash, not at the end. The general >> structure of the flash layout can stay the same on such systems, >> just flipped upside down. \end_layout \begin_layout Itemize move over to the xorg emulator, drop the one we have now as it is not complete enough. (Ron is not so sure about this, since we have done bug-fixes to the xorg emulator) \end_layout \begin_layout Section Comments from Peter Stuge \end_layout \begin_layout Itemize * Ridiculous and error-prone to require commands in three dirs for a build. (Edit targets/foo/bar/Config.lb, run ./buildtarget foo/bar in targets and finally cd targets/foo/bar/baz to make.) (Deps fail on reconfig, I've gotten the wrong payload a couple of times causing annoying extra reboots/hotswaps/fla shes.) \end_layout \begin_layout Itemize * Flash ROM size needs to affect one option, and one option only. Maybe even autodetect it for those building on the target. All other sizes can and MUST be derived from this value. Also: What about option ROMs? Should we aim to produce a ready-to-use lb-2.0-epi a.rom and require a correct (how carefully do we check?) vgabios.rom in order to build with VGA support - or just dump a half- finished product in the user's lap and require them to finish the puzzle on their own? Licensing issues? Is "cat" considered "linking"? \end_layout \begin_layout Itemize * Any redundancy in the config/build process should be removed. I must not need to type the target name more than once. Brings me to.. \end_layout \begin_layout Itemize * Global vs. local builds - pros/cons with kernel style (global) build (always produces arch/x/*Image) and LBv2 style build (produces target/x/y/z/linuxbios.rom for each target) Either way the config/build system must be consistently either global or local. \end_layout \begin_layout Itemize * Support for target variants? Same mobo with/without certain parts populated. Perhaps just sets of default options that can be pre-selected as a base config and then still allow user to change whatever they want. (Kconfig has just one variant per arch, right?) \end_layout \begin_layout Itemize ..basically we want a system that is able to do very complex detailed configuratio ns but that's also able to hide all the details behind "512KiB EPIA-MII 6000E without CF addon" (hypothetical example) \end_layout \begin_layout Itemize Some boards will require more from the user, but when possible a config and build should be dirt simple. \end_layout \begin_layout Itemize One idea is a kind of iterative config with increasing resolution per iteration. Novice users with a known-good board need only complete the first iteration: flash size, board name and board variant if any. Further iterations are optional and allow increasingly specific settings. Think fdisk normal/expert mode. \end_layout \begin_layout Itemize * Payload. I say something must be included in the LB tree or trivially added to a tree by download or command. FILO is candidate for inclusion. What's up with FILO(EB) and FILO(LB) ? Merge them? Make EB default payload? FILO? memtest86? All about making a usable product. memtest86 would have to be explicitly selected in expert mode in favor of the default option that would be able to load an OS. Doesn't matter much if it's only Linux right now because that's the most likely boot candidate for early LB adopters. \end_layout \begin_layout Itemize * Payload config. Long/tedious for EB, simple default for boards with onboard LAN, what to do otherwise? Tricky for FILO. (e.g. EPIA-MII CF boot requires IDE+!PCI, !PCI requires !USB or build fails) filesystems, devices, etc. \end_layout \begin_layout Itemize * Kernel payload and payload utilities - where to get mkelfImage? I had to look hard. Should it be downloaded on demand? Perhaps after the user chooses her payload? Think cygwin installer that downloads selected packages. Maybe a bad idea. \end_layout \begin_layout Itemize * Consistent terminology - the payload seems to have many names in the decompres sion code. ;) \end_layout \end_body \end_document