From 172dab7431600616d1d58f0b8a939d3aa65477cf Mon Sep 17 00:00:00 2001 From: joevt Date: Tue, 13 Aug 2024 00:19:29 -0700 Subject: [PATCH] Update Open Firmware documentation. Add New World ROM Layout notes. Add New World Firmware version notes. Add punctation. Move mention of OF main fcode image from the Open Firmware kernel description section to the boot process section. --- zdocs/developers/openfirmware.md | 171 +++++++++++++++++++++++++++---- 1 file changed, 152 insertions(+), 19 deletions(-) diff --git a/zdocs/developers/openfirmware.md b/zdocs/developers/openfirmware.md index fdc195e78..52799c05a 100644 --- a/zdocs/developers/openfirmware.md +++ b/zdocs/developers/openfirmware.md @@ -24,6 +24,102 @@ drivers. This document focuses on various aspects of Apple's Open Firmware implementation as found in various Power Macintosh models. +## ROM Layout + +### Old World ROMs + +There's a 3 MiB Classic section and a 1 MiB PowerPC section. +Use [tbxi](https://github.com/elliotnunn/tbxi) to split the ROM into parts. + +### New World ROMs + +The ROM only contains the 1MiB PowerPC section. The ROM is divided into sections: + +| Name | Firmware Updater Section Name | Start | Size | Comments | +|:------------------------:|:-----------------------------:|:-----------------------:|:----------------------------------------------------------------------:| +| Start | bb | 0xfff00000 | 0x00003f00 | Exception Vectors. | +| Recovery | rec | 0xfff08000 | 0x00078000 | Usually same as ROM Image. | +| Rom Image | boot | 0xfff80000 | 0x00080000 | Usually same as Recovery. | +| System Configuration | sys | 0xfff03f00 | 0x00000080 | Contains Model specific info. Doesn't exist in early New World Macs. Three bytes in the System Configuration comprise the Mac Product ID. | +| | tst | 0xfff03f80 | 0x00000080 | Contains unit specific info: Serial Number, MAC address. | +| NVRAM | nv | 0x00004000 | 0x00004000 | Contains two copies of NVRAM, 8K each. | + +At the beginning of the Recovery and Rom Image is a header listing subsections. The list differs depending on the firmware version. + +The earliest New World ROMs include all of Open Firmware (main fcode image and driver fcode images) in the Open Firmware subsection. RTAS is an fcode image. + +| Offset | Index | @startvec address field | @startvec size field | +|:------:|:-----:|:-----------------------:|:--------------------:| +| 0x00 | | >dir.inst0 | >dir.inst1 | +| 0x08 | | >dir.filler0 | >dir.filler1 | +| 0x10 | 0 | >dir.HWINIT | >dir.HWINIT-size | +| 0x18 | 1 | >dir.NUB | >dir.NUB-size | +| 0x20 | 2 | >dir.OF | >dir.OF-size | +| 0x28 | 3 | >dir.RTAS | >dir.RTAS-size | +| 0x30 | 4 | >dir.RTAS-LDR | >dir.RTAS-LDR-size | +| 0x38 | 5 | >dir.RTAS-BE | >dir.RTAS-BE-size | +| 0x40 | 6 | >dir.RTAS-LE | >dir.RTAS-LE-size | +| 0x48 | 7 | >dir.BOOT-BEEP | >dir.BOOT-BEEP-size | + +Newer ROMs did away with the RTAS stuff: + +| Offset | Index | @startvec address field | @startvec size field | +|:------:|:-----:|:-----------------------:|:--------------------:| +| 0x00 | | >dir.inst0 | >dir.inst1 | +| 0x08 | | >dir.filler0 | >dir.filler1 | +| 0x10 | 0 | >dir.HWINIT | >dir.HWINIT-size | +| 0x18 | 1 | >dir.NUB | >dir.NUB-size | +| 0x20 | 2 | >dir.OF | >dir.OF-size | +| 0x28 | 3 | >dir.unused0 | >dir.unused0-size | +| 0x30 | 4 | >dir.unused1 | >dir.unused1-size | +| 0x38 | 5 | >dir.unused2 | >dir.unused2-size | +| 0x40 | 6 | >dir.unused3 | >dir.unused3 | +| 0x48 | 7 | >dir.BOOT-BEEP | >dir.BOOT-BEEP-size | + +Starting approximate 2002-11-11 and later, this is the ROM header or first part of @startvec. Different Macs with the same firmware version may include different driver fcode images if the ROM is not large enough to contain all drivers. + +| Offset | Index | @startvec address field | @startvec size field | +|:------:|:-----:|:-----------------------:|:--------------------:| +| 0x00 | | >dir.inst0 | >dir.inst1 | +| 0x08 | | >dir.filler0 | >dir.filler1 | +| 0x10 | 0 | >dir.HWINIT | >dir.HWINIT-size | +| 0x18 | 1 | >dir.OF | >dir.OF-size | +| 0x20 | 2 | >dir.Driver1 | >dir.Driver1-size | +| 0x28 | 3 | >dir.Driver2 | >dir.Driver2-size | +| 0x30 | 4 | >dir.Driver3 | >dir.Driver3-size | +| 0x38 | 5 | >dir.Driver4 | >dir.Driver4-size | +| 0x40 | 6 | >dir.Driver5 | >dir.Driver5-size | +| 0x48 | 7 | >dir.Driver6 | >dir.Driver6-size | +| 0x50 | 8 | >dir.Driver7 | >dir.Driver7-size | +| 0x58 | 9 | >dir.Driver8 | >dir.Driver8-size | +| 0x60 | 10 | >dir.Driver9 | >dir.Driver9-size | +| 0x68 | 11 | >dir.Driver10 | >dir.Driver10-size | +| 0x70 | 12 | >dir.Driver11 | >dir.Driver11-size | +| 0x78 | 13 | >dir.Driver12 | >dir.Driver12-size | +| 0x80 | 14 | >dir.Driver13 | >dir.Driver13-size | +| 0x88 | 15 | >dir.Driver14 | >dir.Driver14-size | +| 0x90 | 16 | >dir.Driver15 | >dir.Driver15-size | +| 0x98 | 17 | >dir.BOOT-BEEP | >dir.BOOT-BEEP-size | + +The latest firmware versions have driver fcode images in one subsection and each driver fcode image has a name and is individually compressed. + +| Offset | Index | @startvec address field | @startvec size field | +|:------:|:-----:|:-----------------------:|:---------------------:| +| 0x00 | | >dir.inst0 | >dir.inst1 | +| 0x08 | | >dir.filler0 | >dir.filler1 | +| 0x10 | 0 | >dir.HWINIT | >dir.HWINIT-size | +| 0x18 | 1 | >dir.OF | >dir.OF-size | +| 0x20 | 2 | >dir.dV1.Drivers | >dir.dV1.Drivers-size | +| 0x28 | 3 | >dir.BOOT-BEEP | >dir.BOOT-BEEP-size | + +The offset for each of the parts is at least 4 byte aligned and has the least significant bit set to 1 if it is lzss compressed. +Only early New World Macs (B&W G3, iMac G3 233-333, PowerBook G3 Lombard) have the RTAS (fcode) and RTAS-BE (executable) parts. +There don't appear to be any ROMs that have NUB, RTAS_LDR, or RTAS-LE. +RTAS is not included in later ROMs so the four parts 3-6 are always 0x00000000 for offset and size. +Since Recovery is smaller than Rom Image, some newer ROMs have BOOT-BEEP of the Recovery section pointing to BOOT-BEEP of the Rom Image section. + +The `>dir.*` fields in the ROM are for the offset and size of the compressed parts. The `>dir.*` fields also exist in RAM starting from `@startvec` but they store the address and size of the parts uncompressed. + ## Open Firmware Versions ### Old World Macs @@ -39,9 +135,44 @@ as found in various Power Macintosh models. | Power Macintosh 6500 | Gazelle | 2.0.3 | 0x330000 | | Power Macintosh G3 v3 | Gossamer | 2.4 | 0x320000 | -### NewWorld Macs +### New World Macs -*TBD* +| Date | OF version | Machine | +|:----------:|:----------:|:-------------------------:| +| 1999-04-01 | 1.0f1 | PowerBook G3 Lombard | +| 1999-04-09 | 1.1f4 | B&W G3 | +| 1999-04-23 | 1.3f2 | iMac (233 - 333 MHz) | + +Newer firmware versions occasionally received firmware updates which could be applied to multiple models so it doesn't make sense to associate a model to a firmware version. +Versions 4.x.x are for 32-bit Power Macs. Version 5.x.x are for 64-bit Power Macs. + +| Date | OF version | +|:----------:|:----------:| +| 2000-02-17 | 3.2.4f1 | +| 2000-07-10 | 3.2f1 | +| 2000-08-11 | 3.2.7f2 | +| 2001-03-20 | 4.1.7f4 | +| 2001-03-21 | 4.1.8f5 | +| 2001-08-01 | 4.2.3f1 | +| 2001-08-16 | 4.2.5f1 | +| 2001-09-14 | 4.1.9f1 | +| 2001-10-11 | 4.2.8f1 | +| 2001-11-20 | 4.2.9f1 | +| 2002-09-30 | 4.4.8f2 | +| 2002-11-11 | 4.5.4f1 | +| 2003-02-20 | 4.6.0f1 | +| 2003-08-22 | 4.6.8f4 | +| 2003-11-21 | 5.1.4f0 | +| 2004-04-06 | 4.8.5f0 | +| 2004-09-21 | 5.1.5f2 | +| 2004-09-23 | 4.8.7f1 | +| 2004-10-26 | 5.1.8f7 | +| 2005-01-21 | 4.9.1f1 | +| 2005-03-23 | 4.8.9f4 | +| 2005-07-12 | 4.9.4f1 | +| 2005-09-22 | 4.9.5f3 | +| 2005-09-30 | 5.2.7f1 | +| 2005-10-05 | 4.9.6f0 | ## Packages @@ -235,28 +366,30 @@ dumpstartvec Apple's Open Firmware 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 +* Set up memory translations for OF execution. +* Relocate itself from ROM to RAM. +* Initialize the Forth runtime environment which includes a dictionary of words. All words are native PPC code. +* Interpret Forth or fcode which adds more words (with PPC code) and data to the dictionary. +* Process low-level exceptions. ## Open Firmware 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 Open Firmware 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 environment 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 Open Firmware 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. +2. HWInit passes control to Open Firmware kernel that prepares OF execution from RAM. `cold-load` is executed. +3. `cold-load` begins interpreting of the main fcode image (`@startvec` `>fcimage`) compiling words to PowerPC code and building the **device tree** - a platform-independent description of the attached HW. The main fcode image and driver fcode images (`@startvec` `>fcfiles`) are interpreted from ROM. +4. `cold-load` passes control to `@startvec` `>'cold-init` which tests for snag keys, optionally executes `nvramrc`, and boots the OS (either by returning to HWInit or executing a `boot` command) or enters the Open Firmware command line. +5. OF returns control to HWInit that initializes several low-level data structures required by the Nanokernel. +6. HWInit passes control to the Nanokernel that initializes the native execution environment and the 68k emulator. +7. 68k emulator executes the start-up code in the Macintosh ROM that initializes various managers. +8. The device tree generated by Open Firmware in step 3 is imported by the Expansion Bus Manager initialization code and stored in the **NameRegistry**. +9. An operating system is located and loaded. ### New World Macs -*TBD* +The PowerPC part is similar to Old World Macs except the Open Firmware and OF Driver subsections need to be decompressed into RAM. +For Classic Mac OS, Open Firmware loads and boots a file of type `tbxi`. This is a New World ROM file in the System Folder which replaces the first 3MiB of the Old World ROM. ## Open Firmware bugs @@ -264,9 +397,9 @@ Apple OF is known to contain numerous bugs. The following table lists some recen | 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. | -| 1.0.5 | /chaos/control `fill-rectangle` is ( ? color y x w h -- ) instead of ( color x y w h -- ) | -| | `$find` is ( name-str name-len -- xt true | pstr name-str name-len false ) instead of ( name-str name-len -- xt true | name-str name-len false ) | -| 2.4 | string literal buffers `"` on the command line are 256 bytes but will overflow if you enter more than 256 bytes. | +| 1.0.5 | `fill-rectangle` in /chaos/control is ( ? color y x w h -- ) but it should be ( color x y w h -- ). This is corrected by Control2.c of BootX which is used to boot Mac OS X. | +| | `$find` is ( name-str name-len -- xt true | pstr name-str name-len false ) but it should be ( name-str name-len -- xt true | name-str name-len false ) | +| 2.0f1, 2.4 | `us` uses `get-usecs` to convert a 64-bit timebase value to a 32-bit microseconds value. That's enough for 71 minutes. After that, anything that uses `us` will cause the OF console to become unresponsive requiring a restart. In Open Firmware 3.x and later, `get-usecs` returns a 64-bit value. | +| 2.4 | string literal buffers `"` on the command line will overflow if the string is more than 256 bytes. | `get-inherited-property notes.txt` discusses known bugs regarding get-inherited-property and map-in in Open Firmware 1.0.5.