[OpenBIOS] [patch] fix "partition-zero"/%BOOT booting for PowerPC targets.

Andrei E. Warkentin andrey.warkentin at gmail.com
Wed Mar 5 09:50:05 CET 2014


Hi,

This is a patch against r1272 which implements fully bootcode booting via
Apple boot partition descriptors. The current implementation in
libopenbios/bootcode_load.c hardcoded values for QUIK (the old
OldWorld bootloader), which is useless if you try to boot anything
else.

In particular, I implemented this to simplify my development and test
cycle on iQUIK (https://github.com/andreiw/quik), but I also tested
this with the NetBSD floppy. The later now boots to stage 2 as well,
although it tries using some functionality unavailable in the OpenBIOS
implementation when compared to Apple's.

I did this in the simplest way possible.

Btw, I see that the optimization bugs are still present. I had to
compile with -O0, otherwise the resulting image doesn't boot (GCC 4.8
here).

-- 
A
-------------- next part --------------
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;
 	    }
 	}
 	    


More information about the OpenBIOS mailing list