mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
acked in this version by Stefan and I want to get it in before continuing to make further changes. Signed-off-by: Ronald G. Minnich <rminnich@gmail.com> Acked-by: Stefan Reinauer <stepan@coresystems.de> git-svn-id: svn://coreboot.org/repository/LinuxBIOSv3@250 f3766cd6-281f-0410-b1cd-43a5c92072e9
1899 lines
46 KiB
Text
1899 lines
46 KiB
Text
#LyX 1.4.2 created this file. For more info see http://www.lyx.org/
|
|
\lyxformat 245
|
|
\begin_document
|
|
\begin_header
|
|
\textclass article
|
|
\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
|
|
All components are seperate modules.
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
The strict seperation of normal/fallback does not exist anymore.
|
|
Any module can be available several times.
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
Commonly used code is shared.
|
|
There is _one_ implementation of printk, and one implementation for each
|
|
compressor.
|
|
\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
|
|
Introduction to the LinuxBIOS device tree
|
|
\end_layout
|
|
|
|
\begin_layout Subsection
|
|
Purpose and function
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The LinuxBIOS device tree is probably the single most important concept
|
|
in LinuxBIOS, 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 compile 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 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.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
At build time, the programmer can specify hardware that is likely to be
|
|
there, although some may not be (a 2-cpu system might have only one CPU
|
|
installed).
|
|
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.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
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 hardware 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 is more complex than might at first seem.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Subsection
|
|
Device tree structures
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
There are three primary objects which are used to manage the LinuxBIOS device
|
|
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.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
These structures are linked together in the static device tree.
|
|
The static device 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 inthe mainboard directory.
|
|
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 place
|
|
in the tree
|
|
\begin_inset Quotes eld
|
|
\end_inset
|
|
|
|
in front of
|
|
\begin_inset Quotes erd
|
|
\end_inset
|
|
|
|
the 0:4.0 device).
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
Each device has a void * which can be filled in, via the dts file, with
|
|
non-generic, i.e., device-specific, information.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
What's the difference between generic and non-generic information? As an
|
|
example, the PCI configuration address or
|
|
\begin_inset Quotes eld
|
|
\end_inset
|
|
|
|
path
|
|
\begin_inset Quotes erd
|
|
\end_inset
|
|
|
|
of a device is generic; there is a path of some sort for every device in
|
|
a system.
|
|
But, not all devices have identical capabilities.
|
|
Some PCI devices have IDE controllers, others do not; some can drive the
|
|
legacy PC XBUS, others can not; and so on.
|
|
In LinuxBIOS V1, we attempted to create devices that were the union of
|
|
all possible devices, but creating 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
|
|
device, always in a file named config.h, e.g.
|
|
src/northbridge/intel/i440gx/config.h.
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
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.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Subsubsection
|
|
More on device source directories, configuration structure and config.h file
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
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.
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
Devices, in some cases, have special control registers that need to be set.
|
|
in a few cases, generic code can handle these operiations: see device/pci_devic
|
|
e.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.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
We show an example of a specific device, below.
|
|
The device is the i440bx emulation.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Float figure
|
|
wide false
|
|
sideways false
|
|
status open
|
|
|
|
\begin_layout Caption
|
|
The files in the i440bx directory.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
[rminnich@q ~]$ ls ~/src/bios/LinuxBIOSv3/northbridge/intel/i440bxemulation/
|
|
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
config.h i440bx.c i440bx.h Kconfig Makefile
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
i440bx.h contains manifest constants defining registers, bits in registers,
|
|
and so on.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
Config.h defines the structures and declarations that allow the static device
|
|
tree to compile.
|
|
We show it below.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Float figure
|
|
wide false
|
|
sideways false
|
|
status open
|
|
|
|
\begin_layout Caption
|
|
config.h for the i440bx
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
extern struct chip_operations northbridge_intel_i440bxemulation_ops;
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
struct northbridge_intel_i440bx_config
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
{
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
/* The various emulators don't always get 440BX right.
|
|
So we are
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
* going to allow users to set the RAM size via Kconfig.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
*/
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
int ramsize;
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
};
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
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.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The Kconfig and Makefile are for the Kbuild system.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Subsection
|
|
Bus
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
Busses, defined in include/device/device.h, connect parent devices to child
|
|
devices.
|
|
Busses are attached to a device, and have child devices attached to them.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Subsection
|
|
Generic device structure and code
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
Generic devices are defined in include/device/device.h.
|
|
Devices:
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
have a path
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
are attached to a bus
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
have sibling devices
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
have a vendor and device ID
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
have a class and hdr type
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
have several booleans, describing state, including enabled, initialized,
|
|
resources have been read, and on the mainboard
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
have a rom address, if a rom is attached to them (e.g.
|
|
VGA)
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
have a set of up to MAX_RESOURCES (currently 12) resources.
|
|
The resources are built into the structure and are not dynamically allocated.
|
|
Functions to manage the resources attached to a device are found in device/devi
|
|
ce_util.c
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
have links, which are usually empty in the case of everything but a bridge
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
have a set of device operations -- these are per-device-type
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
have a set of chip operations, per chip-type
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
have a chip information structure, which is per-chip instance
|
|
\end_layout
|
|
|
|
\begin_layout Subparagraph*
|
|
Path
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
A path names a way of accessing a device.
|
|
These are defined in include/device/path.h.
|
|
The path structure is in essence a case-variant type (struct which includes
|
|
a type and a union of all possible path types).
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Subparagraph*
|
|
Device Resources
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
Resources describe memory and I/O address ranges, IRQs, and DRQs.
|
|
They are define in include/device/resource.h.
|
|
There can be variations of a resource which include things like prefetchable,
|
|
cacheable, and so on.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Subsection
|
|
How are devices created? Via static and dynamic constructors
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
In V2, there was no formal model for creating and/or allocating device structure
|
|
s.
|
|
There was not even a formal convention or way of thinking about such operations
|
|
; this lack of rigor, to some extent, was a result of our limited understanding
|
|
of how to think about the problem, which in turn was a result of the revolution
|
|
in design which followed on the release of the Opteron, with its multiple
|
|
busses per socket, integrated north bridge, ability to site a non-Opteron
|
|
device in an Opteron socket, on-chip HyperTransport router, and so on.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
We learned a lot with V2, and that knowledge underlies the architecture
|
|
of the V3 device tree.
|
|
We have introduced a standardized device id, and are using the notion of
|
|
C++ constructors to unify our thinking.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The device id is very similar to the existing path structure.
|
|
It is defined in include/device/device.h, and is a standard C case-variant
|
|
type with a tag and a union.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The device tree compiler is the static constructor.
|
|
It reads the dts file in the mainboard directory and creates the initial
|
|
device tree, with the devices and busses already set up.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The dynamic constructor is part fo the device tree code.
|
|
There is a set of default constructors, but each device can have its own
|
|
private constructors if needed.
|
|
The constructor structure is simple: it is a standard device id, and a
|
|
pointer to a device_operations structure.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The purpose of a dynamic constructor is to take a standard device path and
|
|
a device id, and create a device structure, with as much information filled
|
|
in as possible.
|
|
At minimum the device id, path, and device operations are filled in.
|
|
|
|
\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 implies 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.
|
|
The device tree, as set up by dts, has two ways it can be traversed.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The first is the hierarchy formed by busses and devices.
|
|
Devices have up to MAX_LINKS links, which are initialized as part of the
|
|
process of creating the static tree.
|
|
These links point to busses.
|
|
A bus has a child device, a device associated with it (e.g.
|
|
a PCI bridge device), and other attributes described elsewhere.
|
|
Some operations, such as enumeration, require that the tree be traversed
|
|
in the hierarchy represented by the bus/device relationship.
|
|
This traversal starts at the root device, and for each link, follows those
|
|
busses to the other devices.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The second is a simple traversal, via linked list, of all the devices.
|
|
This faster, less complex traversal, is performed when there is no need
|
|
to be concerned with the bus/device relationship.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Subparagraph*
|
|
Phase 1 -- making printk work
|
|
\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
|
|
The simple traversal (forall devices) is used for this phase.
|
|
|
|
\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 -- preparation for bus scan
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
These are functions that are required before any PCI operations of any kind
|
|
are run.
|
|
These functions may call printk.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The simple traversal (forall devices) is used for this phase.
|
|
|
|
\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 -- bus scan
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
This phase is typical of all the phases that do a hierarchical traversal.
|
|
It starts at the root device (i.e.
|
|
the mainboard), which uses the distinguished function
|
|
\emph on
|
|
dev_root_phase3
|
|
\emph default
|
|
.
|
|
Some root devices have special setup requirements, and there is a way to
|
|
call this special setup code.
|
|
If the dts has specified a configuration for the root device, it is possible
|
|
to set up an enable_dev function.
|
|
In other words, for any device, it is possible to call some 'preparation'
|
|
code for that device.
|
|
We show an example of such a function below, from the QEMU mainboard.
|
|
First, we show the dts, to show how the chip operations can be enabled.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Float figure
|
|
wide false
|
|
sideways false
|
|
status open
|
|
|
|
\begin_layout Caption
|
|
The dts for the emulation/qemu target
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
/{ config="mainboard,emulation,qemu-i386";
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
~ ~ ~ ~cpus { ...};
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
%%
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
struct mainboard_emulation_qemu_i386_config root = { .nothing = 1, };
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The dts has been shortened for readability.
|
|
Note the use of the 'config=' in the root.
|
|
It specifies that there is an initialized structure after the %% in the
|
|
dts file.
|
|
The structure is at the bottom.
|
|
The dts generates the code shown below.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Float figure
|
|
wide false
|
|
sideways false
|
|
status open
|
|
|
|
\begin_layout Caption
|
|
Code generated for the dts
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
struct mainboard_emulation_qemu_i386_config root = { .nothing = 1, };
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
struct device dev_root = {
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
.path = { .type = DEVICE_PATH_ROOT },
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
.chip_ops = &mainboard_emulation_qemu_i386_ops,
|
|
\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
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The code after the %% is reproduced exactly.
|
|
The dts generates a generic device struct, and initializes the .chip_ops
|
|
struct member to point to the mainboard_emulation_qemu_i386_ops structure.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
When phase 3 is run, the code checks the chip_ops structure member and,
|
|
if it is non-zero, checks the chip_ops->enable_dev pointer and, if it is
|
|
non-zero, calls it.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The mainboard code is shown below.
|
|
The enable_dev function will be called in phase 3,
|
|
\emph on
|
|
before
|
|
\emph default
|
|
any other enumeration is done for that device.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
\begin_inset Float figure
|
|
wide false
|
|
sideways false
|
|
status open
|
|
|
|
\begin_layout Caption
|
|
What the mainboard file looks like with enable_dev
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
static void enable_dev(struct device *dev){
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
printk(BIOS_INFO, "qemu-i386 enable_dev done
|
|
\backslash
|
|
n");
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
}
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
struct chip_operations mainboard_emulation_qemu_i386_ops = {
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
.name = "QEMU Mainboard",
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
.enable_dev = enable_dev
|
|
\end_layout
|
|
|
|
\begin_layout LyX-Code
|
|
};
|
|
\end_layout
|
|
|
|
\end_inset
|
|
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
Root_dev_phase3, which is called with the root
|
|
\emph on
|
|
device
|
|
\emph default
|
|
, calls dev_phase3, for each device attached to the root device.
|
|
The devices are, in fact, bridge devices, i.e.
|
|
the device attached to a bus.
|
|
Dev_phase3, in turn, checks the bus device to see if it is a non-NULL pointer,
|
|
if is enabled, if it has ops and a phase 3 ops; if so, the functions calls
|
|
the bus device's phase 3 op to kick off scanning of busses.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The phase 3 op is different for each type of bus.
|
|
For the root bus, which is statically configured, the phase 3 operation
|
|
walks the set of statically initialized pointers for the root device; for
|
|
the (e.g.) PCI device, which is much more dynamic, the code does actual probing.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
Some busses require a reset operation after scanning.
|
|
The dev_phase3 code will scan its subordinate busses, and then test all
|
|
the busses to see if a reset is needed.
|
|
If so, for each bus that needs a reset, a reset is performed, and
|
|
\emph on
|
|
the bus scanning operation is repeated
|
|
\emph default
|
|
until a reset is no longer needed.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
To sum up, the operation for phase 3, bus scanning, is as follows
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
The root device is the starting point for bus scanning
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
After some initial setup, including an optional call to the chip_ops->enable_dev
|
|
method for the root device, the dev_phase3 function is called with the
|
|
root device as the parameter.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
The dev_phase3 function, after checking that the bus has the ability to
|
|
be scanned (i.e.
|
|
the device has an ops->phase3 pointer), scans the bus by calling the phase3
|
|
function for the bus.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
If scanning results in a need for a reset, the reset(s) are performed on
|
|
the links that need it, and
|
|
\emph on
|
|
the scan operation is repeated
|
|
\emph default
|
|
.
|
|
This cycle continues until no resets are needed.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The per-device phase 3 operation for a bus has a mutually recursive relationship
|
|
with dev_phase3.
|
|
The per-device function is called with the pointer to the device that was
|
|
passed into dev_phase3.
|
|
The per-device phase 3 iterates over the set of child links (i.e.
|
|
busses) that are attached to the device and, for each link, checks the
|
|
chip_ops of the child link device for each link, and determines whether
|
|
to call the enable_dev for each child link device.
|
|
The one quite non-intuitive action that some of these functions take is
|
|
to enable the child link device, whether the child link device is enabled
|
|
or not in the configuration.
|
|
This enable is done in order to ensure that child busses are properly enumerate
|
|
d, whether they are enabled or not.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
Once the child link devices have been properly examined and (for some busses)
|
|
set up for enumeration, the per-device phase 3 operation iterates over
|
|
the child link devices one more time and calls dev_phase 3 for each child
|
|
link device.
|
|
This final loop completes the enumeration for this level of the hierarchy.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
At the end of the per-device phase 3 operation, the structure of the physical
|
|
device tree has been completely determined, including both the static devices
|
|
and any dynamic devices, such as cards plugged into PCI slots.
|
|
For each level of the tree, the structure which define the devices, and
|
|
busses, have been filled in, and the presence or absence of devices has
|
|
been determined.
|
|
At the end of this pass, it is possible to determine what resources each
|
|
device will need, and to allocate those resources as needed.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Subparagraph*
|
|
Post codes:
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
root_dev_phase3 entry: 0x40
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
After enable_dev is tested and potentially called: 0x41
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
dev_phase3 entry: 0x42
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
dev_phase3 entry: 0x4e (note: since this is a recursive function, the post
|
|
codes can cycle from 4e to 43 and back again)
|
|
\end_layout
|
|
|
|
\begin_layout Itemize
|
|
root_dev_phase3 exit: 0x4f
|
|
\end_layout
|
|
|
|
\begin_layout Subparagraph*
|
|
Phase 4
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
The point of phase 4 is to determine what resources are needed for each
|
|
device; to allocate those resources; and to configure the devices with
|
|
those resource values.
|
|
Resources are determined in one of two ways.
|
|
Some devices, if present, have static resource requirements (e.g.
|
|
superio parts, which have a fixed requirement for two I/O addresses).
|
|
Other devices have resource requirements that can be determined by reading
|
|
registers (such as Base Address Registers in PCI) and are hence dynamic.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
A similar mutual recursion is employed, starting again at the root.
|
|
The root devices phase 4 ops are called with the root device as a parameter.
|
|
For each link on the device, and for each type of resource that is needed
|
|
to be determined, the compute_allocate_resource function is called.
|
|
This function takes a bus, resource, mask, and type as a parameter.
|
|
As busses as scanned, and resources are read, the mask is applied ot the
|
|
resource and compared to the type, so as to select the type of resource
|
|
desired.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
Once the reading of resources is done, the root device has IO resources
|
|
as resource 0, and mem resources as resource 1.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
After the generic resource reading has been done, there is one special case,
|
|
for VGA, which overrides the standard hierarchical traversal.
|
|
If VGA console is enabled, the bridges must be configured in such a way
|
|
as to pick a
|
|
\begin_inset Quotes eld
|
|
\end_inset
|
|
|
|
primary
|
|
\begin_inset Quotes erd
|
|
\end_inset
|
|
|
|
VGA device.
|
|
Once the resources have been enumerated, a function called allocate_vga_resourc
|
|
e is called.
|
|
This function traverses the devices in non-hierarchical order, and selects
|
|
one of them as the VGA device for the so-called
|
|
\begin_inset Quotes eld
|
|
\end_inset
|
|
|
|
compatibilty chain
|
|
\begin_inset Quotes erd
|
|
\end_inset
|
|
|
|
.
|
|
Once this device is selected, the function walkss the tree from the device
|
|
to the root, enabling the VGA CTL bit in each bridge.
|
|
|
|
\end_layout
|
|
|
|
\begin_layout Standard
|
|
Once this phase has been done, all the memory and IO resources have been
|
|
enumerated and allocated to each device, and to each bridge, in the system.
|
|
This phase is easily the most complex of all the phases in stage 2.
|
|
\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
|
|
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 version of x86emu/biosemu, drop the one we have now
|
|
as it is not complete enough.
|
|
(Ron is not so sure about this, since we have done our own bug-fixes to
|
|
x86emu)
|
|
\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 decompressi
|
|
on code.
|
|
;)
|
|
\end_layout
|
|
|
|
\end_body
|
|
\end_document
|