283 lines
10 KiB
Plaintext
283 lines
10 KiB
Plaintext
Slimline Open Firmware - SLOF
|
|
|
|
Copyright (C) 2004, 2012 IBM Corporation
|
|
|
|
|
|
Index
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1.0 Introduction to Open Firmware
|
|
2.0 Using the source code
|
|
2.1 Build process
|
|
2.2 Overview of the source code
|
|
2.4 Extending the Forth engine
|
|
3.0 Limitations
|
|
4.0 Submitting patches
|
|
5.0 Coding style
|
|
|
|
|
|
1.0 Introduction to Slimline Open Firmware
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
The IEEE Standard 1275-1994 [1], Standard for Boot (Initialization Configura-
|
|
tion) Firmware, Core Requirements and Practices, was the first non-proprietary
|
|
open standard for boot firmware that is usable on different processors and
|
|
buses. Firmware which complies with this standard (also known as Open Firmware)
|
|
includes a processor-independent device interface that allows add-in devices
|
|
to identify itself and to supply a single boot driver that can be used,
|
|
unchanged, on any CPU. In addition, Open Firmware includes a user interface
|
|
with powerful scripting and debugging support and a client interface that
|
|
allows an operating system and its loaders to use Open Firmware services
|
|
during the configuration and initialization process. Open Firmware stores
|
|
information about the hardware in a tree structure called the
|
|
"device tree". This device tree supports multiple interconnected system
|
|
buses and offers a framework for "plug and play"-type auto configuration
|
|
across different buses. It was designed to support a variety of different
|
|
processor Instruction Set Architectures (ISAs) and buses.
|
|
|
|
The full documentation of this Standard can be found in [1].
|
|
|
|
Slimline Open Firmware (SLOF) is now an implementation of the IEEE 1275
|
|
standard that is available under a BSD-style license. Please see the file
|
|
LICENSE for details.
|
|
|
|
|
|
2.0 Using the source code
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
This version of SLOF currently supports two major platforms ("boards" in the
|
|
SLOF jargon):
|
|
|
|
- js2x : The PowerPC 970 based systems JS20, JS21 and the PowerStation
|
|
- qemu : Used as partition firmware for pseries machines running on KVM/QEMU
|
|
|
|
The following sections will give you a short introduction about how to compile
|
|
and improve the source code.
|
|
Please read the file INSTALL for details about how to install the firmware on
|
|
your target system.
|
|
|
|
|
|
2.1 Build process
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
To build SLOF you need:
|
|
- Recent GNU tools, configured for powerpc64-linux
|
|
- GCC: 3.3.3 and newer are known to work
|
|
- Binutils: use a version as new as possible
|
|
- Subversion (for retrieving the x86 emulator)
|
|
|
|
- set the CROSS variable
|
|
- something like export CROSS="powerpc64-unknown-linux-gnu-"
|
|
when using a cross compiler
|
|
or
|
|
- export CROSS=""
|
|
when using a native compiler
|
|
|
|
- For building SLOF for the PowerStation, it is necessary to
|
|
download a x86 emulator which is used to execute the BIOS
|
|
of VGA card; to download the x86 emulator following steps are
|
|
required:
|
|
- cd other-licence/x86emu/
|
|
- ./x86emu_download.sh # this downloads the x86 emulator sources
|
|
- cd -
|
|
|
|
- Now you can compile the firmware.
|
|
- For building SLOF for JS20, JS21 or the PowerStation, type:
|
|
make js2x
|
|
You also might want to build the takeover executable by typing:
|
|
make -C board-js2x takeover
|
|
- For building SLOF as the partition firmware for KVM/QEMU, type:
|
|
make qemu
|
|
The resulting ROM image "boot_rom.bin" can then be found in the main
|
|
directory.
|
|
|
|
|
|
2.2 Overview of the source code
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
The SLOF source code is structured into the following directories:
|
|
|
|
- llfw : The Low-Level Firmware - this part is platform-specific firmware
|
|
that is responsible to boot the system from the reset vector to a
|
|
state where it is possible to run the Open Firmware Forth engine
|
|
(i.e. it sets up the necessary CPU registers, intializes the memory,
|
|
does some board-specific hardware configuration, etc.)
|
|
|
|
- slof : The code for the Open Firmware environment, including the Forth
|
|
engine (called "Paflof") and the necessary Forth source files.
|
|
|
|
- rtas : The Run-Time Abstraction Services, which can be used by the operating
|
|
system to access certain hardware without knowing the details.
|
|
See [2] for a description of these services.
|
|
|
|
- clients : Code that runs on top of the Open Firmware client interface.
|
|
Currently, there are two clients:
|
|
- net-snk : Used for network bootloading (a TFTP client)
|
|
- takeover : A separate binary that can be used for bootstrapping
|
|
SLOF on a JS20/JS21 (see FlashingSLOF.pdf for details).
|
|
|
|
- drivers : Driver code for various hardware (currently only NIC drivers).
|
|
|
|
- lib : Libraries with common code.
|
|
|
|
- romfs / tools : Tools that are required for building the firmware image.
|
|
|
|
- board-* : The board directories contain all the code that is unique to the
|
|
corresponding platform.
|
|
|
|
|
|
2.3 The Open Firmware engine
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Open Firmware (OF) is based on the programming language Forth.
|
|
SLOF use Paflof as the Forth engine, which was originally developed by
|
|
Segher Boessenkool. Most parts of the Forth engine are implemented in C, by
|
|
using GNU extensions of ANSI C, (e.g. assigned goto, often misnamed "computed
|
|
goto"), resulting in a very efficient yet still quite portable engine.
|
|
|
|
The basic Forth words, so-called primitives, are implemented with
|
|
a set of C macros. A set of .in and .code files are provided, which
|
|
define the semantic of the Forth primitives. A Perl script translates
|
|
these files into valid C code, which will be compiled into the Forth engine.
|
|
The complete Forth system composes of the basic Forth primitives and
|
|
a set of Forth words, which are compiled during the start of the Forth
|
|
system.
|
|
|
|
Example:
|
|
Forth primitive 'dup'
|
|
|
|
dup ( a -- a a) \ Duplicate top of stack element
|
|
|
|
|
|
prim.in:
|
|
cod(DUP)
|
|
|
|
prim.code:
|
|
PRIM(DUP) cell x = TOS; PUSH; TOS = x; MIRP
|
|
|
|
Generated code:
|
|
|
|
static cell xt_DUP[] = { { .a = xt_DOTICK }, { .c = "\000\003DUP" },
|
|
{ .a = &&code_DUP }, };
|
|
|
|
code_DUP: { asm("#### " "DUP"); void *w = (cfa = (++ip)->a)->a;
|
|
cell x = (*dp); dp++; (*dp) = x; goto *w; }
|
|
|
|
Without going into detail, it can be seen, that the data stack is
|
|
implemented in C as an array of cells, where dp is the pointer to the top of
|
|
stack.
|
|
|
|
For the implementation of the Open Firmware, most of the code is added as
|
|
Forth code and bound to the engine. Also the system vectors for all kinds of
|
|
exceptions will be part of the image. Additionally a secondary boot-loader
|
|
or any other client application can be bound to the code as payload,
|
|
e.g. diagnostics and test programs.
|
|
|
|
The Open Firmware image will be put together by the build
|
|
process, with a loader at the start of the image. This loader
|
|
is called by Low Level Firmware and loads at boot time the Open
|
|
Firmware to it's location in memory (see 1.3 Load process). Additionally
|
|
a secondary boot loader or any other client application can be bound
|
|
to the code as payload.
|
|
|
|
The Low Level Firmware (LLFW) is responsible for setting up the
|
|
system in an initial state. This task includes the setup of the
|
|
CPUs, the system memory and all the buses as well as the serial port
|
|
itself.
|
|
|
|
|
|
2.4 Extending the Forth engine
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
In the following paragraphs it will be shown how to add
|
|
new primitive words (i.e., words implemented not by building
|
|
pre-existing Forth words together, but instead implemented in
|
|
C or assembler). With this, it is possible to adapt SLOF to
|
|
the specific needs of different hardware and architectures.
|
|
|
|
|
|
To add primitives:
|
|
|
|
For a new primitive, following steps have to be done:
|
|
|
|
+ Definition of primitive name in <arch>.in
|
|
- cod(ABC) defines primitive ABC
|
|
|
|
You can also use the following in a .in file, see existing
|
|
code for how to use these:
|
|
- con(ABC) defines constant ABC
|
|
- col(ABC) defines colon definition ABC
|
|
- dfr(ABC) defines defer definition ABC
|
|
|
|
+ Definition of the primitives effects in <arch>.code
|
|
- PRIM(ABC) ... MIRP
|
|
|
|
The code for the primitive body is any C-code. With
|
|
the macros of prim.code the data and return stack of
|
|
the Forth engine can be appropriately manipulated.
|
|
|
|
|
|
3.0 Limitations of this package
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
On a JS20 the memory setup is very static and therefore there are
|
|
only very few combinations of memory DIMM placement actually work.
|
|
|
|
Known booting configurations:
|
|
|
|
* 4x 256 MB (filling all slots) -- only "0.5 GB" reported.
|
|
* 2x 1 GB, slots 3/4 -- only "0.5 GB" reported.
|
|
|
|
Known failing configurations
|
|
|
|
* 2x 256 MB, slots 3/4
|
|
* 2x 256 MB, slots 1/2
|
|
|
|
On a JS20 SLOF wil always report 0.5 GB even if there is much more memory
|
|
available.
|
|
|
|
On a JS21 all memory configurations should work.
|
|
|
|
|
|
4.0 Submitting patches
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Patches for SLOF should be made against https://github.com/aik/SLOF,
|
|
the master branch and posted to slof@lists.ozlabs.org.
|
|
The patches must be signed using "Signed-off-by" tag with a real name to
|
|
confirm that you certify the Developer Certificate of Origin Version 1.1,
|
|
see [3] for details.
|
|
|
|
|
|
5.0 Coding style
|
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
New C code submitted to SLOF should follow the coding style guidelines
|
|
for the Linux kernel [4] with the following exceptions:
|
|
|
|
- in the event that you require a specific width, use a standard type
|
|
like int32_t, uint32_t, uint64_t, etc. Don't use Linux kernel internal
|
|
types like u32, __u32 or __le32.
|
|
|
|
New Forth code should use 4 space indentations and no tabs. Patches for
|
|
the old code should keep the existing style which usually is
|
|
3 space indentation.
|
|
|
|
New assembly code submitted to SLOF should follow the coding style
|
|
guidelines for the Linux kernel [4], i.e. indent with tabs, not with spaces.
|
|
|
|
|
|
Documentation
|
|
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
[1] IEEE 1275-1994 Standard, Standard for Boot (Initialization Configuration)
|
|
Firmware: Core Requirements and Practices
|
|
|
|
[2] PAPR Standard, Power.org(TM) Standard for Power Architecture(R) Platform
|
|
Requirements (Workstation, Server), Version 2.4, December 7, 2009
|
|
|
|
[3] Developer Certificate of Origin Version 1.1
|
|
http://developercertificate.org/
|
|
|
|
[4] Linux kernel coding style
|
|
https://github.com/torvalds/linux/blob/master/Documentation/CodingStyle
|