Skip to content

Theory ARC

pappadf edited this page Sep 14, 2026 · 1 revision

ARC

This page owns: the firmware standard Windows NT expects on a non-x86 machine, and every place this machine does not have one.

ARC is the Advanced RISC Computing specification. For our purposes it is simply this: the set of things NT's PowerPC loader assumes the firmware will do for it. Understanding ARC is understanding what NT is asking for, which is the only way to understand why the answers have to be manufactured here.


1. What ARC is, and who it was for

ARC came out of the early-1990s effort to make RISC workstations run shrink-wrapped operating systems. It standardises four things:

  1. a configuration tree describing the hardware,
  2. a firmware vector table of functions a loaded program can call,
  3. a set of environment variables saying what to boot and from where,
  4. NVRAM to keep those variables in.

Windows NT's MIPS, Alpha and PowerPC ports were all written against it. On the PowerPC side that meant PReP machines from IBM and Motorola, whose firmware provided ARC natively.

NT does not treat ARC as optional or as one of several possibilities. Its loader has no hardware probing to fall back on: if the firmware cannot answer, the boot stops.


2. The configuration tree

A tree of components, each with a class, a type, an identifier string and optional configuration data. NT's loader walks it to learn what exists, and the kernel later converts it into the registry's hardware description.

On this machine the veneer builds one that looks like this (abridged):

device-tree                      class System   ← the root, and its Identifier
  PowerPC-604                    class Processor
    Cache, Cache
  memory                         class Memory
  multi(0)                       class Adapter  ← the first PCI bus
    scsi(0) → cdrom(0) → fdisk(0)
    scsi(1) → disk(0)  → rdisk(0)
    net(0), serial(0), serial(1), key, point, video
  multi(1) … multi(3)                           ← the second bridge and two more

Two details from this tree have had outsized consequences.

The root's Identifier is what Setup matches a HAL against. Here it is device-tree — the Open Firmware root node's name, faithfully converted — and it matches nothing in NT's table, so Setup falls back to asking the user. → How Setup chooses a HAL

Identifier strings on devices decide which drivers bind. The SCSI controllers were originally reported with a model string NT did not recognise, so no miniport claimed them and the machine had no disk. Eleven patched bytes fixed it — the ledger, row 5.


3. ARC paths

ARC names a device by the route to it:

multi(0)scsi(1)disk(0)rdisk(0)partition(2)
  │       │      │      │         └── partition 2
  │       │      │      └── logical unit
  │       │      └── the disk
  │       └── the second SCSI controller
  └── the PCI bus

Anything after the device part is a file path:

multi(0)scsi(1)disk(0)rdisk(0)partition(1)\os\winnt40\osloader.exe

These strings appear everywhere — in the environment, in the loader's arguments, in NT's registry, and in \ArcName\ symbolic links inside the running system. Being able to read one at a glance saves a lot of time.


4. The firmware vector table

A table of function pointers the firmware publishes and a loaded program calls. The useful ones here:

GetPeer, GetChild, GetParent, GetComponent walk the configuration tree
GetConfigurationData a component's resource list
Open, Close a device or a file
Read, Seek, Write, GetReadStatus I/O on an open handle
GetFileInformation size and attributes
GetEnvironmentVariable, SetEnvironmentVariable the environment
GetMemoryDescriptor walk the memory map
GetTime, GetRelativeTime the clock
Halt, PowerDown, Restart, Reboot ending things

The entries are at fixed indices in the table, which is how a loader compiled years earlier calls a firmware written later.

On this machine every one of them is implemented by the veneer on top of Open Firmware's client interface. When NT's loader reads a sector, the chain is:

OSLOADER's FAT reader → ARC Seek + Read → the veneer → OF client interface → disk

5. The environment

The variables NT's loader needs, with the values this machine uses:

Variable Example Who reads it
SYSTEMPARTITION multi(0)scsi(1)disk(0)rdisk(0)partition(1) the loader; Setup
OSLOADER …partition(1)\os\winnt40\osloader.exe the firmware, to find the loader
OSLOADPARTITION …partition(2) the loader, for the OS
OSLOADFILENAME \WINNT the loader
OSLOADOPTIONS NODEBUG the loader
LOADIDENTIFIER Windows NT Workstation Version 4.00 the boot menu
AUTOLOAD, COUNTDOWN YES, 5 the boot menu
LASTKNOWNGOOD FALSE the loader
CONSOLEIN, CONSOLEOUT multi(0)serial(0)line(0) everything

Read the first five together and the design is clear: the firmware finds the loader on the system partition, and the loader finds the operating system on a possibly different partition. That separation is why a system partition exists at all.


6. Where it is supposed to live — and does not

On a real ARC machine the environment lives in NVRAM, written by the firmware's own setup utility, and it survives a reboot. That is the whole point: you install NT, it records where it put itself, and the machine can start it again.

This machine has no ARC NVRAM. Open Firmware has its own nvram, in its own format, owned by Apple's firmware; nothing translates between the two. So on this machine the ARC environment is plain memory, and a reboot loses every variable in it.

The consequences run right through the project:

  • Setup writes the boot configuration correctly, through the HAL — and the restart loses it.
  • Booting an installed system therefore requires injecting the environment from outside before the loader asks for it.
  • The HAL synthesises SYSTEMPARTITION from the loader's own disk list, because otherwise Setup refuses to start — which is policy in the wrong place, and known to be.

Those are ledger rows 11, 12 and 16, and together they are probably the single most valuable outstanding piece of work: an nvram-backed environment store is what stands between "boots under a test rig" and "boots". → Booting the installed system


7. ARCINST.EXE, and the other thing that is missing

ARC machines ship with a firmware utility — ARCINST on many of them — that partitions a disk and creates the system partition: a FAT partition holding the loader, which the firmware can read before any NT filesystem exists.

NT's Setup will not begin without one. It does not create it; it expects the firmware vendor's tool to have done so.

This machine has no such tool, so the disk has to arrive already partitioned. That is what tools/mkarcdisk.py does — a plain MBR and plain FAT16 partitions, nothing machine-specific. → Preparing disks


8. What this machine has instead — a summary

ARC expects This machine has
A configuration tree Open Firmware's device tree, converted by the veneer
A firmware vector table the veneer, over Open Firmware's client interface
An environment in NVRAM RAM, lost on reboot, injected from outside
ARCINST to prepare a disk mkarcdisk.py, run on the host
A machine identifier NT recognises device-tree, which matches nothing — hence a patched TXTSETUP.SIF

Every row of that table is a place where something had to be built, and four of the five are still imperfect.


Further reading

Clone this wiki locally