OpenBSD/macppc netboot (a.k.a. how I bricked and unbricked my iBook G4)

I attempted to upgrade my iBook G4 to OpenBSD 6.4 recently, and seeing as the system was a bit untidy due to various bits of hacking over the 6.3 cycle, I decided to do a complete reinstall instead of simply upgrading.

Bricking the iBook

I took backups, loaded the install sets onto a USB stick, and then rebooted into the 6.4 install kernel. Unfortunately, the USB stick I had decided to use functions really badly when it gets hot, and it was quite warm from shuffling all the files around. This meant that the installer crashed due to I/O timeouts from the USB disk while unpacking the sets, and when I attempted to reboot the system to make a second attempt, the kernel froze while syncing the disks, so I had to force the machine to power off.

It was only after this that I realised that the FAT partition from which the firmware normally loads the bootloader had of course been reformatted, which meant that the machine totally failed to boot. The iBook I have also has a faulty CD drive, which meant that I had only one way left to boot it up.


Unbricking the iBook

Thankfully, I have other OpenBSD machines around from which I can netboot the iBook, namely the Xserve. I went and took a look at the INSTALL.macppc file, which mentions an OpenFirmware command for booting such PowerPC machines from the network:

boot enet:,ofwboot /bsd.rd
                (netboot from a pre-configured dhcp/tftp/nfs
                server; "ofwboot" will be obtained from the tftp server,
                while "bsd.rd" will be obtained from the NFS server,
                as specified by the "next-server" and "root-path" dhcp

So, the magic ingredients here are DHCP, TFTP and NFS. First, I connected the iBook to the Xserve over ethernet, and configured the Xserve with the address I then consulted the manuals of dhcpd(8) and tftpd(8), created a new directory, /hack, and copied the ramdisk kernel and bootloader there. I then crafted the following dhcpd.conf:

subnet netmask {
        option routers;
        range dynamic-bootp;

        host fruitcake {
                hardware ethernet XX:XX:XX:XX:XX:XX;
                filename "ofwboot";
                option root-path "/hack";

Importantly, OpenFirmware sends DHCP requests, but the OpenBSD/macppc bootloader sends BOOTP requests -- these are not the same! By default, dhcpd(8) doesn't assign addresses from a dynamic pool to BOOTP clients, and this must be explicitly enabled with the dynamic-bootp option. (Also, the filename parameter isn't strictly necessary here, as I'm specifying it explicitly on the OpenFirmware command line.)

I then performed NFS configuration, by adding /hack -subnet -mask to /etc/exports. I then started portmap(8), nfsd(8) and mountd(8), in that order. (One of the OpenBSD developers has a short guide on setting NFS up in simple scenarios like this.) I then started dhcpd(8), using the configuration file above, and tftpd(8), configured to change to serve requests from /hack.

I turned the iBook on, got to an OpenFirmware prompt, and then entered the command from the install documentation. The OpenFirmware ROM then made a DHCP request and acquired an address, and then loaded the bootloader over TFTP. The bootloader then made a BOOTP request and acquired an address, and then mounted the NFS filesystem exported from the Xserve, and then loaded the ramdisk kernel (or at least, it did once I fixed the permissions so that users other than root could read the kernel file).

I was then able to (finally!) install 6.4 on the iBook.