As of r1280 OpenBIOS now correctly implements booting via partition-zero boot block.
http://git.qemu.org/?p=openbios.git;a=commit;h=1ac3fb92c109f5545d373a0576b87750c53cce19
That's the power of Open Source.
Showing posts with label OpenBIOS. Show all posts
Showing posts with label OpenBIOS. Show all posts
Tuesday, March 18, 2014
Wednesday, March 5, 2014
Making OpenBIOS support Apple partition-zero booting
To speed up my development cycle on iQUIK and make it less painful I really needed to get OpenBIOS to boot via bootcode correctly. The current sources (r1272) hard code the load address for the legacy QUIK bootloader, which makes it useless for me or for anyone else (like the NetBSD or OpenBSD bootloaders).
I didn't try very hard, but the end result works, and hopefully the OpenBIOS guys will just take my fix.
SVN workflow seems so...senescent compared to git. Sigh.
I didn't try very hard, but the end result works, and hopefully the OpenBIOS guys will just take my fix.
SVN workflow seems so...senescent compared to git. Sigh.
Index: forth/debugging/client.fs
===================================================================
--- forth/debugging/client.fs (revision 1272)
+++ forth/debugging/client.fs (working copy)
@@ -28,7 +28,13 @@
0 state-valid !
variable want-bootcode
+variable bootcode-base
+variable bootcode-size
+variable bootcode-entry
0 want-bootcode !
+0 bootcode-base !
+0 bootcode-size !
+0 bootcode-entry !
variable file-size
Index: libopenbios/bootcode_load.c
===================================================================
--- libopenbios/bootcode_load.c (revision 1272)
+++ libopenbios/bootcode_load.c (working copy)
@@ -12,13 +12,11 @@
#define printf printk
#define debug printk
-#define OLDWORLD_BOOTCODE_BASEADDR (0x3f4000)
-
int
bootcode_load(ihandle_t dev)
{
int retval = -1, count = 0, fd;
- unsigned long bootcode, loadbase, offset;
+ unsigned long bootcode, loadbase, offset, loadsize, entry;
/* Mark the saved-program-state as invalid */
feval("0 state-valid !");
@@ -33,34 +31,59 @@
loadbase = POP();
#ifdef CONFIG_PPC
- /* ...except that QUIK (the only known user of %BOOT to date) is built
- with a hard-coded address of 0x3f4000. Let's just use this for the
- moment on both New World and Old World Macs, allowing QUIK to also
- work under a New World Mac. If we find another user of %BOOT we can
- rethink this later. PReP machines should be left unaffected. */
+ /*
+ * Apple OF does not honor load-base and instead uses pmBootLoad
+ * value from the boot partition descriptor.
+ *
+ * Tested with:
+ * a debian image with QUIK installed
+ * a debian image with iQUIK installed (https://github.com/andreiw/quik)
+ * an IQUIK boot floppy
+ * a NetBSD boot floppy (boots stage 2)
+ */
if (is_apple()) {
- loadbase = OLDWORLD_BOOTCODE_BASEADDR;
+ feval("bootcode-base @");
+ loadbase = POP();
+ feval("bootcode-size @");
+ loadsize = POP();
+ feval("bootcode-entry @");
+ entry = POP();
+
+ printk("bootcode base 0x%lx, size 0x%lx, entry 0x%lx\n",
+ loadbase, loadsize, entry);
+ } else {
+ entry = loadbase;
+
+ /* Load as much as we can. */
+ loadsize = 0;
}
#endif
bootcode = loadbase;
offset = 0;
- while(1) {
+ if (loadsize) {
+ if (seek_io(fd, offset) != -1)
+ count = read_io(fd, (void *) bootcode, loadsize);
+ } else {
+ while(1) {
if (seek_io(fd, offset) == -1)
- break;
+ break;
count = read_io(fd, (void *)bootcode, 512);
offset += count;
bootcode += count;
+ }
}
/* If we didn't read anything then exit */
if (!count) {
goto out;
}
+
+ printk("entry = 0x%lx\n", entry);
/* Initialise saved-program-state */
- PUSH(loadbase);
+ PUSH(entry);
feval("saved-program-state >sps.entry !");
PUSH(offset);
feval("saved-program-state >sps.file-size !");
Index: libopenbios/load.c
===================================================================
--- libopenbios/load.c (revision 1272)
+++ libopenbios/load.c (working copy)
@@ -1,6 +1,6 @@
/*
* Creation Date: <2010/06/25 20:00:00 mcayland>
- * Time-stamp: <2010/06/25 20:00:00 mcayland>
+ * Time-stamp: <2014-03-05 03:18:49 andreiw>
*
* <load.c>
*
Index: packages/mac-parts.c
===================================================================
--- packages/mac-parts.c (revision 1272)
+++ packages/mac-parts.c (working copy)
@@ -1,6 +1,6 @@
/*
* Creation Date: <2003/12/04 17:07:05 samuel>
- * Time-stamp: <2004/01/07 19:36:09 samuel>
+ * Time-stamp: <2014-03-05 03:42:07 andreiw>
*
* <mac-parts.c>
*
@@ -237,6 +237,19 @@
size = (long long)__be32_to_cpu(par.pmPartBlkCnt) * bs;
if (want_bootcode) {
+ ucell loadaddr = 0;
+ ucell loadsize = 0;
+ ucell loadentry = 0;
+
+ loadaddr = __be32_to_cpu(par.pmBootLoad);
+ loadsize = __be32_to_cpu(par.pmBootSize);
+ loadentry = __be32_to_cpu(par.pmBootEntry);
+ PUSH(loadaddr);
+ feval("bootcode-base !");
+ PUSH(loadsize);
+ feval("bootcode-size !");
+ PUSH(loadentry);
+ feval("bootcode-entry !");
offs += (long long)__be32_to_cpu(par.pmLgBootStart) * bs;
size = (long long)__be32_to_cpu(par.pmBootSize);
}
@@ -249,6 +262,10 @@
di->size_hi = size >> BITS;
di->size_lo = size & (ucell) -1;
+ if (want_bootcode) {
+ goto out;
+ }
+
/* We have a valid partition - so probe for a filesystem at the current offset */
DPRINTF("mac-parts: about to probe for fs\n");
DPUSH( offs );
@@ -277,7 +294,7 @@
/* If we have been asked to open a particular file, interpose the filesystem package with
the passed filename as an argument */
- if (!want_bootcode && strlen(argstr)) {
+ if ( strlen(argstr)) {
push_str( argstr );
PUSH_ph( ph );
fword("interpose");
@@ -286,6 +303,10 @@
goto out;
} else {
DPRINTF("mac-parts: no filesystem found on partition %d; bypassing misc-files interpose\n", parnum);
+
+ /* Fail out instead of having macparts_load get called uselessly, allowing trying the next
+ boot device */
+ ret = 0;
}
}
This does make booting iQUIK on OpenBIOS now very easy.
qemu-system-ppc -hda ~/src/quik/distrib/floppy-cfg.img -prom-env "boot-file=hd:3"
Getting PowerPC OpenBIOS to run on QEMU
- You've apt-get installed qemu, but qemu-system-ppc boots to a blank (white or black) screen?
- You've pulled the OpenBIOS SVN, built qemu-openbios.elf, but it boots to a blank screen?
On serial output, you might see "<< set_property: NULL phandle" messages, and the CPU is stuck in a perpetual ISI.
Have no fear. Apparently GCC versions > 4.6 miscompile OpenBIOS, so you need to disable optimization. This is presently set to "-Os" under "Makefile.target". Setting it t "-O0" should do.
I'll probably investigate this deeper after fixing partition-zero booting...
A
Have no fear. Apparently GCC versions > 4.6 miscompile OpenBIOS, so you need to disable optimization. This is presently set to "-Os" under "Makefile.target". Setting it t "-O0" should do.
I'll probably investigate this deeper after fixing partition-zero booting...
A
Sunday, September 15, 2013
iQUIK - the new old PowerMac bootloader for OldWorld machines
About three quarters of a year ago I found a PowerBook 3400c in the trash pile at work. Given my ongoing nostalgia for PowerPC and OpenFirmware, I couldn't pass up the opportunity to reminisce with this PowerBook.
It is by far the oldest mac I've had. The UMAX S900 I dumpster dove for back in 2002 was a dual 604e. This baby is a 603ev. That's three generations behind my old G4 iBook. It's OF is slightly less broken than 1.0.5 on the S900 - at least it doesn't default stdio to serial, and doesn't need nvramc patches to boot from disk. The 3400c booted into MacOS, but clearly it was asking for Linux.
Unfortunately, the best you could do is install via old miBoot floppies, and get a 2.2(!)-based Debian system, just like I had to on the S900 ten whole years ago. Of course you could painfully and slowly upgrade releases, only to realize you can't actually boot a 2.4 kernel with an initrd with the OldWorld bootloader, QUIK. Staring at a "VFS panic" message after investing a week into slowly getting to /that/ point would be bound to enrage most people just toss the aging laptop into trash...
I guess I have an odd fascination with obsolete hardware. I've decided to take ownership of the QUIK code, fixing many of its bugs and limitations. The effort is now called iQUIK and is available for everybody at https://github.com/andreiw/quik.
iQUIK is a Linux bootloader for "OldWorld" PowerMacs. "OldWorld" PowerMacs are all machines that have OpenFirmware, but that don't have built-in USB. Due to a lacking firmware implementation, the typical Yaboot bootloader cannot be used on "OldWorld" machines.
Some highlights:
...but that's not what I wanted to write this post about. I was curious if I could boot iQUIK successfully with the QEMU PowerPC system emulator and OpenBIOS. Turns out yes, but it's a bit painful. The problem is that OpenBIOS doesn't support the mac's "partition-zero" booting, e.g.
So how to boot on QEMU, then? We could cheat and load the non-munged ELF file the boot code is created from, but I don't have my 3400c nearby to compile with. Instead we will convince OpenBIOS to load our code just like a PowerMac would.
This example assumes:
There you have it.
Of course it would be ideal to just implement bootsector-zero support or even this hack as an nvramrc patch, but unfortunately QEMU PPC has no NVRAM support. Boo...
It is by far the oldest mac I've had. The UMAX S900 I dumpster dove for back in 2002 was a dual 604e. This baby is a 603ev. That's three generations behind my old G4 iBook. It's OF is slightly less broken than 1.0.5 on the S900 - at least it doesn't default stdio to serial, and doesn't need nvramc patches to boot from disk. The 3400c booted into MacOS, but clearly it was asking for Linux.
I guess I have an odd fascination with obsolete hardware. I've decided to take ownership of the QUIK code, fixing many of its bugs and limitations. The effort is now called iQUIK and is available for everybody at https://github.com/andreiw/quik.
iQUIK is a Linux bootloader for "OldWorld" PowerMacs. "OldWorld" PowerMacs are all machines that have OpenFirmware, but that don't have built-in USB. Due to a lacking firmware implementation, the typical Yaboot bootloader cannot be used on "OldWorld" machines.
Some highlights:
- You can install and boot Debian Wheezy (the current stable release)
- You can install the boot loader on any medium, including floppy.
- Initrd image work fine, as do 2.2., 2.4 and 2.6 kernels.
- Can boot any kernel/initrd/argument combos without a quik.conf.
- Can list filesystems (only ext2 supported at the moment).
- Works around OF/hw bugs with an innovative shim layer. At least the many bugs on the 3400c.
- Single-stage installation for robustness, using partition-zero boot block and bootstrap partition.No more LILO-style block maps.
You can see the fairly exhaustive documentation at https://github.com/andreiw/quik/blob/master/README. It's only really been tested on a 3400c, although I'm getting a G3 PDQ (that's the last OldWorld PowerBook!) for testing soon.
...but that's not what I wanted to write this post about. I was curious if I could boot iQUIK successfully with the QEMU PowerPC system emulator and OpenBIOS. Turns out yes, but it's a bit painful. The problem is that OpenBIOS doesn't support the mac's "partition-zero" booting, e.g.
0 > boot ata0/ata-disk@0:0How does "partition-zero" booting work? The mac partition table contains a structure that describes the disk offset of the bootloader, its size and where to load it. The bootloader has to be plain binary (i.e. not XCOFF). iQUIK leverages this by copying the boot code into it's own partition and setting up the boot descriptor in the partition table to point to it. http://www.opensource.apple.com/source/bless/bless-11/README.BOOTING is a pretty good document that describes this more in-depth.
So how to boot on QEMU, then? We could cheat and load the non-munged ELF file the boot code is created from, but I don't have my 3400c nearby to compile with. Instead we will convince OpenBIOS to load our code just like a PowerMac would.
This example assumes:
- You have qemu-system-ppc.
- You have floppy.img from the github quik/distrib.
- You created an install.img: FAT partitioned, ext2 on only FAT partition with the Debian files from http://ftp.nl.debian.org/debian/dists/wheezy/main/installer-powerpc/current/images/powerpc/hd-media/
- Note: take the 'initrd-size' out of yaboot.conf file you downloaded above.
Steps are pretty simple. We launch the simulator like so:
qemu-system-ppc -hda floppy.img -hdb install.img -serial stdioAt the "0 >" prompt in the framebuffer window we type the following commands to switch the firmware to serial port for input/output. You might wonder why we couldn't use the "prom-env" option to set output-device and input-device? It doesn't work. Heh.
0 > " /pci/mac-io/escc/ch-a" output 0 > " /pci/mac-io/escc/ch-a" inputAnd now paste the rest of this script into terminal you ran QEMU from. Of course, you could put it on bootable media, but...
0 value ih \ \ size and load-base need to match \ SECOND_BASE and SECOND_SIZE in \ quik/include/layout \ 10000 value size setenv load-base 3e0000 \ \ boot-file specifies where iQUIK will look \ for the configuration file. This corresponds to \ the second ATA disk (-hdb), first FAT partition. \ setenv boot-file /pci/mac-io/ata-1/disk@1:1/yaboot.conf \ \ OpenBIOS doesn't know how to parse the MAC "partition-zero" \ boot descriptor, so we'll manually load it. XXX:2 refers \ to the Apple_Boostrap partition on -hda, which in the floppy.img \ image is the first parition (wonky indexing... yes). \ \ I don't really understand why OpenBIOS needs the seek to 0. \ Seems like a bug... \ " /pci/mac-io/ata-1/disk@0:2" open-dev to ih 0 " seek" ih $call-method . load-base size " read" ih $call-method . \ \ Based on OpenBIOS libopenbios/bootcode_load.c \ load-base saved-program-state >sps.entry ! size saved-program-state >sps.file-size ! bootcode saved-program-state >sps.file-type ! -1 state-valid ! \ \ Now can boot. For completeness probably should set \ /chosen/bootargs but iQUIK can handle the inconsistency. \ ih close-dev goYou should now see iQUIK in the framebuffer window (not the serial, because we haven't set the input-device and output-device env variables). You can press the tab key to show the boot labels available. Just press enter to boot the default 'install'.
There you have it.
Of course it would be ideal to just implement bootsector-zero support or even this hack as an nvramrc patch, but unfortunately QEMU PPC has no NVRAM support. Boo...
Labels:
bootloader,
iQUIK,
Linux,
OldWorld,
OpenBIOS,
OpenFirmware,
PowerMac,
PowerPC,
QEMU,
QUIK
Subscribe to:
Posts (Atom)
