# OpenFirmware in Power Macintosh *compiled from various sources by Max Poliakovski.* [Open Firmware](https://en.wikipedia.org/wiki/Open_Firmware) is a platform-independent boot firmware architecture covered by an IEEE standard. All PowerMacintosh computers run OpenFirmware except the very first generation that uses [Nubus](https://en.wikipedia.org/wiki/NuBus) instead of [PCI](https://en.wikipedia.org/wiki/Peripheral_Component_Interconnect). OpenFirmware is used to perform hardware identification and initialization during the booting process after power-on. It also provides a platform-independent description of the attached devices available for operating systems. In this respect, OpenFirmware can be compared with [BIOS](https://en.wikipedia.org/wiki/BIOS), widely used in the PC world. Being based upon the [Forth programming language](https://en.wikipedia.org/wiki/Forth_(programming_language)), OpenFirmware offers an operating system, an interactive environment as well as a programming language in one package. Its shell can be used as well by users for controlling the boot enviroment as by developers for developing and debugging device drivers. This document focuses on various aspects of Apple's OpenFirmware implementation as found in various PowerMacintosh models. ## OpenFirmware Versions ### Old World Macs | ROM dump/Machine | BootROM codename | OF version | OF image offset | |:----------------------------------- :|:----------------:|:-------------:|:---------------:| | Power Macintosh 7300/7600/8600/9600 | TNT | 1.0.5 | 0x330000 | | Bandai Pippin | Pip | 1.0.5 | 0x330000 | | Power Macintosh/Performa 6400 | Alchemy | 2.0 | 0x330000 | | Power Macintosh G3 desktop | Gossamer | 2.0f1 | 0x320000 | | PowerBook G3 Wallstreet v2 | GRX | 2.0.1 | 0x330000 | | Power Macintosh 4400/7220 | Zanzibar | 2.0.2 | 0x330000 | | Power Macintosh 6500 | Gazelle | 2.0.3 | 0x330000 | | Power Macintosh G3 v3 | Gossamer | 2.4 | 0x320000 | ### NewWorld Macs *TBD* ## OpenFirmware image ### Old World Macs OpenFirmware in OldWorld Macs is stored in the monolithic 4MB ROM. Its hibernated image is located at offset `0x320000` or `0x330000` from beginning of the ROM. That corresponds to the physical address `0xFFF20000` or `0xFFF30000`, respectively. The size of the OpenFirmware image varies from 98KB (v1.0.5) to 172KB (v2.4). Apple's OpenFirmware image has the following structure: | Section type | Architecture | Relative Size (v1.0.5) | Relative Size (v2.4) | |:------------------:|:------------:|:----------------------:|:--------------------:| | OF kernel | PowerPC | 26% | 18% | | OF main code | FCode | 62% | 51% | | OF device packages | FCode | 12% | 31% | OF image is wrapped in the COFF container. At the start of the image, a COFF file header and a section header are located. The following example parses the COFF headers of the OF image from the Gossamer ROM v3: ``` org 0xFFF20000 ; OF COFF file header dc.w 0x1DF ; COFF magic dc.w 1 ; number of sections dc.l 'Gary' ; Gary Davidian's signature replaces time and date dc.l 0 ; ptr to the symbol table dc.l 0 ; number of entries in the symbol table dc.w 0 ; size of the optional header dc.w 0 ; flags ; OF COFF section header dc.b '.text', 0, 0, 0 ; section name dc.l 0 ; physical address dc.l 0 ; virtual address dc.l 0x2ADB0 ; section size in bytes (= 171KB) dc.l 0x3C ; file offset to section data dc.l 0 ; file offset to section relocations dc.l 0 ; file offset to line number entries dc.w 0 ; number of relocation entries dc.w 0 ; number of line number entries dc.l 0x20 ; section flags (this section contains executable code) ``` Right after the COFF section header, a vital OF kernel data structure called `StartVec` is located. It contains among others several important offsets into the OF image for finding all required OF parts. That's also the location HWInit passes control to when invoking OF: ``` org 0xFFF2003C ; OF execution starts here mflr r11 ; save return address to HWInit in R11 bl OF_kernel_start ; pass control to OF kernel ; LR will contain physical address of StartVec ; Begin of StartVec structure ; All offsets are from the beginning of the .text section (0xFFF2003C) FFF20044 dc.l 0x7918 ; offset to the FCode stream of the OF main package ... FFF2007C dc.l 0x28C48 ; offset to the last driver in the device packages ... FFF20084 dc.l 0x7720 ; offset to the last Forth word descriptor of the kernel ``` ### OpenFirmware internals Apple's OpenFirmware contains a small kernel implemented in the native PowerPC code. This kernel performs the following actions: * set up memory translation for OF execution * relocate itself from ROM to RAM * initialize Forth runtime environment * recompile OF main image from FCode to native PPC code * pass control to recompiled OF that starts building the device tree * process low-level exceptions ## OpenFirmware and the Macintosh boot process ### Old World Macs 1. In response to power coming on, HWInit code in the Power Macintosh ROM performs initialization of the memory controller and the basic I/O facilities as well as some self-testing. After that, the startup chime is played. 2. HWInit passes control to OpenFirmware kernel that prepares OF execution from RAM. OF builds the **device tree** - a platform-independent description of the attached HW. 3. OF returns control to HWInit that initializes several low-level data structures required by the Nanokernel. 4. HWInit passes control to the Nanokernel that initializes the low-level virtual machine and the 68k emulator. 5. 68k emulator executes the start-up code in the Macintosh ROM that initializes various managers. 6. The device tree generated by the OpenFirmware in step 2 is imported by the Expansion Bus Manager initialization and stored in the **NameRegistry**. 7. An operating system is located and loaded. ### New World Macs *TBD* ## OpenFirmware bugs Apple OF is known to contain numerous bugs. The following table lists some recently discrovered bugs, not mentioned elsewhere. | OF version affected | Bug description | |:-------------------:|-----------------| | 2.0f1, 2.4 | A numerical overflow in `um/mod used by get-usecs-60x` causes the OF console to become unresponsible after approx. 71 minutes. You have to restart your computer once the bug is triggered. |