A tiny guide to Open Firmware

What is Open Firmware

Open Firmware is the hardware-independent firmware (computer software which loads the operating system) that the XO runs.

It was developed by Mitch Bradley at Sun Microsystems, and used in post-NuBus PowerPC-based Apple Macintosh computers (though it has been dropped with Apple's transition to Intel processors), Sun Microsystems SPARC based workstations and servers, IBM POWER systems, and PegasosPPC systems, among others. On those computers, Open Firmware fulfills the same tasks as BIOS does on PC computers.

gentoo uses YaBoot BootLoader for Open Firmware.

The Open Firmware user interface includes a FORTH-based shell interface. FORTH is a powerful high level language that is remarkably compact. A complete Forth development environment including compiler, decompiler, assembler, disassembler, source level debugger, and assembly language debugger is present in the XO boot ROM (SPI FLASH). With the Open Firmware Forth system, you can directly access all of the hardware devices on the XO, use built-in functions like selftest diagnostics and games, and even write complete applications, without needing any external tools. The bulk of Open Firmware is written in Forth, so the source level debugger can be used to debug Open Firmware itself.

Links

varia

programming in forth

Single board computers and Forth

There a few SBC cards equipped with Forth in their rom, for example there are a few 68HC11 that card came with FORTH embedded in the ROM on the cpu chip. A later variant added floating point to the ROM and I exchanged this CPU for all the previous ones to get this feature. I had actually heard of FORTH before I got my hands on one of these SBC's. A friend in Oregon had told me casually, one day, that he had written some code in FORTH and that it was very strange stuff indeed. Used things like commas as commands. Strange indeed. But I needed a very low power CPU card to run some sensors I was building for a mooring that would have to run on batteries for long periods unattended. And this SBC had the least current draw of any that I found. So ... I had to learn FORTH.I bought the book by Leo Brodie, "STARTING FORTH" (available on-line at FORTH, INC) and started learning. With the 68HC11 SBC, the card became the language lab. Hooked it up to a PC running a serial terminal program (BitCom for the 80386 cpu -- still use it today!) and applied power. The card sent a startup message line and was now ready for me to program.FORTH is a peculiar sort of O/S, reminiscent of the BASIC O/S that came on the early Apple computers. It consists of defined WORDS which you can call directly from the command line. You can also define new WORDS using the old WORDS and any new WORDS you have previously defined. Typing the name of any of these WORDS will cause that WORD to be executed. If you think SUBROUTINE for WORD, then this isn't all that strange. Generally, one builds a program by defining WORDS that do specific things -- collect data from an ADC, generate ping gates on a digital line, convert a number to dB, etc. Each word can be tested by itself until it is working properly. When the whole program is done, there will be a last WORD (I always call mine MAIN) that starts the whole thing going.Another peculiarity of FORTH is the use of stacks to hold data. WORDS exchange data using the stack. If a WORD requires some input data, the typical way to provide it is to put the data on the stack before calling the WORD. Being FORTH, this is done as schematically as possible: if the data were held in locations called, say, DATA1 and DATA2, and the WORD that needed the data was called PROCESS, then the calling sequence would look likeDATA1 @DATA2 @PROCESSIn other words, naming a data variable and calling the WORD "@" (fetch) puts the data on the stack and naming (typing) the WORD "PROCESS" evokes this code. The answer will, in all likelihood, also be placed on the stack.On the 68HC11 board, I tested the program by loading it into RAM in the upper 32K of the 64K memory map. The SBC had a socket for a memory IC. When I was happy with the program, I would make a Motorola S-file image of the program (by running a program supplied by NMI) and save it in a capture file on the PC. I used this file to burn an EPROM which I installed in place of the RAM chip and there was an operating sensor controller. (There are some details left out here, such as autostarting the code. I'll add links to documents on these details or you can check out NMI directly). The picture below is one of the 68HC11 cards offered by NMI:NMIS-L-0021BI've used these SBC's to control acoustic sensors, including TAPS-6 and TAPS-8, as well as weather stations and little lab gadgets where a bit of smarts were required. One nice feature is the ability to enter a sleep mode where current draw is too low to measure accurately (maybe 100 microamps). I use a RTC chip to issue timed interrupts to wake up the CPU and cause it to collect dataMore recently, I've switched over to a 68HC12 SBC. This was partly to get the faster processor on the HC12 and partly in order to save a large amount of code I've written for the HC11 which can be migrated over to the HC12 chip. I figured out how to interface the HC12 SBC to a compact-flash RAM card so that I had lots of memory for data and even for programs (see the DOWNLOADS page). The new-generation TAPS-6 uses a controller with the 68HC12 SBC and a 128 MB CF-RAM card. The operating programs run in RAM on the SBC and are loaded from the CF-RAM card as needed. A relatively small section of the CF-RAM card is devoted to program space and the rest is available for data. This is the processor in the WHAPS/SandScan series of sensors, as well.There are other choices available for SBC's for embedded systems. The Persistor is a terrific card with many nice features; I have one that I'm going to embed in something one of these days. The main drawback -- to me -- is that the only way to program this card is via a complicated programming environment in, of course, C. I've already mentioned I don't like C. The Rabbit cards are also pretty slick. They have quite a choice of cards with various I/O possibilities, including USB and ETHERNET. I have two of these that I'd also like to embed in something. Again, however, the code support comes in a C environment. Ugh.

The Apple BIOS, hardware-independent firmware

Most Apple G3/G4 systems use a modified version of the Open Firmware standard. These machiens are normally referred to as "NewWorld Macs". Open Firmware acts as a type of bios for the PowerPC system, it is responsible for identifying various hardware components and uses a series of environment variables to all the user or developer to modify the boot behavior of the system. Open Firmware is pretty easy to access and navigate once you know how, this guide walks you through the basics, so you can get to know your system a little better.

Boot Process

The boot process starts with the PowerPC processor executing its reset vector as specified by the Hardware Initialization code. The boot ROM stored in NVRAM provides power on self test (POST - diagnostics), and initializes enough of the system to load Open Firmware. These POST tests are run in native PowerPC code and involve checksum testing, memory testing, detection of the manufacturing test pin and test manager support. With the new family of iMac systems, additional pre-firmware diagnostics are performed due to the addition of the UniNorth and KeyLargo ICs. When enough initialization has occurred to execute Open Firmware, the boot chime is played and Open Firmware is loaded.

Booting from a CD-ROM

The easiest route for most people will be to use an Ubuntu CD. If you have a CD, and if your machine supports booting directly off the CD, great! Simply insert your CD, reboot, and proceed to the next chapter.

Note that certain CD drives may require special drivers, and thus be inaccessible in the early installation stages. If it turns out the standard way of booting off a CD doesn't work for your hardware, revisit this chapter and read about alternate kernels and installation methods which may work for you.

If you have problems booting, see the section called “Troubleshooting the Installation Process”.

Currently, the only PowerPC subarchitectures that support CD-ROM booting are PReP (though not all systems) and New World PowerMacs. On PowerMacs, hold the c key, or else the combination of Command, Option, Shift, and Delete keys together while booting to boot from the CD-ROM.

If your system doesn't boot directly from CD-ROM, you can still use the CD-ROM to install the system. On NewWorlds, you can also use an OpenFirmware command to boot from the CD-ROM manually. Follow the instructions in the section called “Booting NewWorld Macs from OpenFirmware” for booting from the hard disk, except use the path to yaboot on the CD at the OF prompt, such as

0 > boot cd:,\app.elf

Booting from Hard Disk

Booting from an existing operating system is often a convenient option; for some systems it is the only supported method of installation.

To boot the installer from hard disk, you will have already completed downloading and placing the needed files

Booting NewWorld Macs from OpenFirmware

You will have already placed the vmlinux, initrd.gz, yaboot, and yaboot.conf files at the root level of your HFS partition in the section called “Hard Disk Installer Booting for NewWorld Macs”. You will now have to boot into OpenFirmware. At the prompt, type

0 > boot hd:x,app.elf

replacing x with the partition number of the HFS partition where the kernel and yaboot files were placed, followed by a Enter. On some machines, you may need to use ide0: instead of hd:. In a few more seconds you will see a yaboot prompt

Booting with TFTP

Booting from the network requires that you have a network connection and a TFTP network boot server (DHCP, RARP, or BOOTP).

Currently, PReP and New World PowerMac systems support netbooting.

On machines with Open Firmware, such as NewWorld Power Macs, enter the boot monitor and use the command

0 > boot enet:0

If this doesn't work, you might have to add the filename like this:

0 > boot enet:0,app.elf

PReP and CHRP boxes may have different ways of addressing the network. On a PReP machine, you should try

0 > boot net:server_ipaddr,app.elf,client_ipaddr

OpenFirmware Init

Open Firmware will then probe the system's I/O buses to determine the device configuration and build a device tree, which describes the hardware it has located, the system will then examine the values of its enviroment variables. If the auto-boot? variable is flagged as true, the system will then read the value contained within the boot-device variable and attempt to boot from that device. If additional information is required the boot-file variable is read. If the auto-boot? variable is flagged as false, the system will halt the boot process and drop to the Open Firmware user interface.

Default Boot Device

The default boot device on Apple systems is "hd:,\\:tbxi". The system will automatically convert "hd" into the appropriate device path, as hd is simply an alias. The notation "\\" tells the system to start searching for "blessed" folders (directories) starting on the first HFS or HFS+ partition found on the system. The final part, "tbxi", tells the system to look for files of type tbxi. All versions of MacOS have a folder known as System Folder that is "blessed", and contains a MacOS Boot ROM file which is of type tbxi. The Boot ROM file is simply a stripped ELF executable image wrapped with a forth boot script. A "blessed" folder is simply one with a special attribute (or flag) set on it. The system will search all HFS partitions for a bblessed folder and a file of type tbxi within it, if none are located, the boot will fail. The system will always select the first one found, unless the boot-device is modified to a specific partition id.

Old World vs New World

Apple's Open Firmware is part of their ROM-in-RAM design approach originally used in the first iMac systems. The approach uses a small ROM that contains sufficient code to initialize the hardware and load an operating system. The rest of the system code, that on previous Mac systems (old world) resided on a physical ROM (chip) is now loaded from disk or from network into RAM. Open Firmware is part of this "New World" boot system.

Overview of Open Firmware

Open Firmware is a boot environment developed using the Forth programming language. Open Firmware exists to provide a machine independent means of loading operating systems, from a variety of boot devices. Open Firmware probes the PCI bus for devices and possible Open Firmware device drivers for those devices. These drivers can either be integrated into the Open Firmware or provided on an external device, thus providing plug and play capabilities for new boot devices. Open Firmware is then capable of using these drivers to load an operating system from the device.

On the latest revision of Apple systems Open Firmware provides a variety of functions. One of the key functions of Open Firmware is to configure the UniNorth and Keylargo ICs, to constract a device tree, probe devices, include any device drivers and finally select a boot device. Open Firmware includes FCode channels for UltraDMA/33, Firewire (1394) and USB hardware channels. Interrupts are determined by information contained within the device tree.

Open Firmware capabilities

Apple's Open Firmware can load ELF binary images directly from a HFS standard, HFS extended or a ISO9660 file system. The ELF image can be loaded using the Open Firmware user interface command boot along with the syntax hd:5,\\image.elf. The "hd" is the alias for the hard disk, 5 is the partition id, and "\\image.elf", tells the system to look for image.elf in a blessed folder on that partition.

Open Firmware supports booting from a variety of devices, to provide some element of user-friendliness, Open Firmware supports the use of aliases for a variety of devices. For example, the primary hard disk and primary CD/DVD-ROM drives are represented by hd and cd aliases. These alises are constructed from the device-tree by Open Firmware, in reality the alias hd actually is a path within the device-tree such as /pci@f2000000/mac-io@17/ata-4@1f000/disk@0.

Navigating Open Firmware

Open Firmware is easily accessible at boot time by using a simple key combination of Command + Option (alt) + O + F. This key combination must be used during the initial boot sequence (as soon as the audible chime is heard), and held util the distinctive black on white, text based Open Firmware user interface appears. Open Firmware will display a message similar to this:

The Open Firmware interface is similar to the boot rom interface on Sun Microsystems SPARC systems, in that, it stores its environment variables through the use of the setenv command and variables can be viewed through the printenv command. Another commonality between the two systems, is that both are stored on NVRAM. While Open Firmware has several system and user definable variables, we will look at those involved in the boot process.

Apple's Open Firmware supports a variety of variables for network booting, these include variables that handle ip, subnet masks, router/gateways which can be used for network-booting the system using a boot protocol such as BOOTP.

auto-boot?

uses a boolean (true/false) value to determine whether to automatically boot or to drop to open firmware.

boot-device

is a string value and is used to specify the boot device, partition and file type to load on boot.

boot-command

is also a string value, and is used to supply an alias for booting the OS (eg. the default is mac-boot).

boot-file

is another string value, and contains the location of a bootinfo.txt style script. This is a legacy open firmware variable that can be used to specify a chrp style script, similar to those used on the IBM RS/6000.

Navigating: Examining Hardware Devices

Open Firmware can be used to provide valuable insight into the hardware configuration of the system. At boot time, Open Firmware collects information regarding each device within the system and builds a device-tree, there are a variety of commands available to examine not only the device information and current configuration, but also some of the underlying Forth source code that is used in the Open Firmware drivers for those devices. This type of hardware information is extremely useful for tuning performance, correcting errors or trying to implement new drivers for a device.

ls - displays contents of the current path in the device tree.

devalias - provides a list of short alias names for key hardware devices.

words - provides a list of forth scripts associated with the selected device.

source - executes a particular forth script.

load - loads a image from disk, cd, network or another device.

go - execites the currently loaded image.

see - displays the source code for a particular forth script.

The ls, dev, pwd and .properties commands can be used to navigate around the device-tree, this can be useful for learning which specific hardware devices are interconnected. The structure of the device tree reveals which particular hardware devices are connected to which hardware bus structures, for example the device tree indicates which devices are connected to which PCI bus and host controller, which devices are connected to the USB controller and so on. Device driver programmers can look at the underlying Forth scripts and examine the state of that Open Firmware will leave particular hardware devices in. Programmers can also re-write the forth scripts using the Open Firmware interface to test the behavior of particular hardware devices. A segment of the device tree for the pci bus is show below:

The segement of the device tree shown above, clearly shows the uni-north AGP controller and the ATI Rage Mobility are off pci1, while most of the input/output devices are driven from pci2. The second segement shows an example of the mac-io portion of the tree with an ATA device and a seperate USB portion of the tree. Finally pci3 has the ethernet device, and may contain additional devices such as a firewire bus (on the iMac DV for example).

Looking at the source

You can use the see command to look at some of the forth code that is used for a particular device. The code below is from the USB probe function in Open Firmware. It calls other routines and is pretty simple.

The above code is a snapshot from Open Firmware, and is Copyright Apple Computer, it is displayed here for educational purposes only.

Accessing the device-tree in Linux

You do not need to be in open firmware to look at the device tree. You can examine it from within the /proc file system by simply cd'ing to /proc/device-tree. For example, you can cd to aliases within the device tree, then use ls to list the aliases, and cat to display the contents of an alias (eg. cat enet reveals /pci@f4000000/ethernet).

It might be a little easier to navigate the device tree under Linux, find what you are looking for then examine it in more detail in open firmware.

Disclaimer

Examining the contents of open firmware on your system can give you a wealth of information about your system, however modification of variables or forth code within open firmware itself can lead to your system being unusable if done incorrectly. We do not provide any gaurentee or warrenty with this document, and cannot be held liable for any damage to your system you may cause as a result of using information contained within this document. We strongly recommend that you only use this document to examine the contents of your system, and avoid modifications unless you know what you are doing.