Booting a PowerBook from a LiveCD image on an USB-Stick

I have an old Apple PowerBook G4 with a broken CD/DVD drive. For most practical purposes, the broken drive is no issue. However, if you’re going to re-install the laptop, it becomes one. Luckily, the PowerBook is able to boot from USB…

At first, I tried following the instructions on "LiveUSB on PPC" found in Gentoo’s Wiki, but that didn’t work out at first. I then found a blog entry titled "Creating a bootable USB Stick with Mac OS X in 10 easy steps&quot. Combining the two lead to success, so here’s what I did:

  • I downloaded the latest PowerPC release of Finnix, a &quot self-contained, bootable Linux CD distribution&quot from the project’s front page.

  • I re-named the ISO image from finnix-ppc-105.iso to finnix-ppc-105.dmg. Also, I displayed the file’s information in Finder by right-clicking on the file icon and selecting "Show Information&quot. I doubt that this step is required but it certainly didn’t do any harm.

  • From a shell, aka "Terminal Window&quot, I used the command diskutil list to find the device path to my USB drive. In my case, it was /dev/disk6.

  • I then unmounted the drive by running

    $ diskutil unmountDisk /dev/disk6

  • Using good, old dd(1), I wrote the disk image to the USB drive:

    $ sudo dd if=finnix-ppc-105.dmg of=/dev/disk6 bs=1m
  • Finnally, I unmounted the drive by running:

    $ diskutil eject /dev/disk6

In order to boot the PowerBook from the USB drive, I had to drop into Open Firmware. In case you didn’t know it, this is done by holding down Cmd+Option+o+f right after the computer is turned on.

The next step was to find the device node of the bootable USB drive. To do this, I browsed the device tree for any USB node that had a disk child node.

> dev /
> ls

In my case, the USB drive was at /pci@f2000000/usb@1b,1/disk@1.

The instruction found on the Gentoo wiki assign the cd alias to that node, so I did that, too, by running:

> devalias cd /pci@f2000000/usb@1b,1/disk@1

This allowed me to finally boot from the USB drive like this:

> boot cd:,\:tbxi

Why Open Firmware is pretty neat

I’ve just been impressed by the power of Open Firmware again. I’m currently tinkering with the decrementer and time base registers on a PowerPC processor and I need to find out if some of my assumptions are correct.

One way to do that is to compile my C code, load and start it over the network and see if things work the way I think they should work. While this works, it’s somewhat time consuming.

Another way of doing this is to use the Open Firmware user interface – a full featured Forth system. As such, it offers very powerful features during development. In fact, everything entered at the client interface could also be compiled into a forth word, which could even be included in the firmware’s dictionary.

So let’s take a look at the base conversion features Forth offers.

0> decimal
OK
0> 63 19 - dup .
44 OK
1> hex .
2c OK

The code above switches the default number base to decimal. Then the (decimal) numbers 63 and 19 are placed on the stack and a subtraction (63 – 19) is performed. What ends up on the stack is the result of the math operation. We duplicate the item (basically saving a copy for later use) and then pop and display the top value. The result is 44, i.e. the result of the subtraction when calculating with decimal numbers.

Now we’re switching the number base to hexadecimal again, and display the stack’s topmost value (we saved the calculation result before). The result is 2c, i.e. 44 displayed as a hexadecimal number.

Next up, logical operations. A left shift is defined as

lshift (value count -- value)

meaning you place value on the stack, place the amount of bits you want it to be shifted (count) on the stack and when the lshift word returns, the shifted value will be on the stack. So take a look at this:

o> decimal 63 19 - hex
OK
1> 1 swap lshift
OK
1> dup .
100000000000  OK

The first line is the subtraction explained above. Then, we push a 1 on the stack and swap the two top most items. The stack now looks like ( 1 2c ) which we’ll feed the lshift operator. We duplicate the result and display one copy. And there’s bitmask, where the 44th bit is set.

Going further to the more firmware specific parts. The Open Firmware implementation I’m using right now offers a word that let’s me read the boot processor’s HID0 register. The word is hid0@, it takes no input and places the register’s value on the stack. Similarily, there’s a word that let’s me write the register, it’s hid0!. It takes one argument from the stack and doesn’t place anything on the stack.

So take the next sequence. I’m assuming it’s executed right after the previously quoted sequence, so the calculated bitmask should be on the stack.

1>hid0@
OK
2> dup .
100080000000 OK
2> or dup .
100080000000 OK
1>hid0!
OK
0>

1>

First, we read the HID0’s value and display it in a non-destructive manner. Then we or the bitmask and the register value and display it’s result. Note that the result is the same, meaning the 44th bit was already set. Then, we write the value back to the register.

This is just an example of the power of Open Firmware. I’m going to play some other tricks right now, but I wanted this to be written down first so I can look it up again.

Open Source SLOF

I just tried to download and build the SLOF open source release. The SLOF release itself can be downloaded here (note that an IBM ID, aka registration, is required). Let me just say that is has been a very pleasant experience – everything worked out of the box!

The release tar ball contains a file INSTALL with pretty good instructions on what needs to be done to compile the code. What’s missing is a link to the required JS20/JS21/Bimini System-Interface Code. It’s on the SLOF download page but it took me a moment to realize it’s there.

Once the system interface code has been downloaded and extracted, run the install-oco.sh script that’s included in the tar ball. It takes one parameter, the path to the extracted SLOF source code.

Also, the x86emu code needs to be pulled from the coreboot subversion repository. Execute the x86emu_download.sh script in other-licence/x86emu/ and it will do that for you.

Finally, export the CROSS environment variable. In my case I had to set it to "ppu-" by running

export CROSS=ppu-

Then, just run this command to compile the code:

make js2x

Almost all of the information above is included in the INSTALL file with the exception of the missing link. Again, this is a very pleasant surprise to me. There are other vendors where Open Source does not work so flawlessly. Hey there, Intel ;-).