dingusppc/zdocs/openfirmware.md
2021-11-29 22:35:12 +01:00

6.9 KiB

OpenFirmware in Power Macintosh

compiled from various sources by Max Poliakovski.

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 instead of PCI.

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, widely used in the PC world.

Being based upon the 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 native execution enviroment 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 code 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 unresponsive after approx. 71 minutes. You have to restart your computer once the bug is triggered.