[OpenBIOS] [PATCH] load: fix generation of /chosen bootpath property

Mark Cave-Ayland mark.cave-ayland at ilande.co.uk
Fri Jun 28 12:23:27 CEST 2013


It seems that some OS require the bootpath property to be the full, unaliased
path to the selected boot device, so use get-instance-path to ensure that
this is the case.

There is a slight issue here when auto-probing a partition, since the package
arguments won't contain the chosen partition id which semms to be mandatory
for bootpath. In order to resolve this, scan for a special
selected-partition-args property in the instance chain before
generating the bootpath, and if it exists use that for the device package
arguments instead.

Using the mechanism, we can set this property once we have auto-probed a
partition in mac-parts.c so bootpath is generated correctly. Finally it is
possible to remove the current hack of overwriting bootpath when calling
open-dev on a mac-parts partition, which would confuse some bootloaders
if they read bootpath after opening a new device.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
---
 openbios-devel/forth/admin/userboot.fs   |    2 +-
 openbios-devel/forth/debugging/client.fs |   84 +++++++++++++++++++++++++-----
 openbios-devel/forth/device/property.fs  |    2 +-
 openbios-devel/packages/mac-parts.c      |   43 +++++----------
 4 files changed, 88 insertions(+), 43 deletions(-)

diff --git a/openbios-devel/forth/admin/userboot.fs b/openbios-devel/forth/admin/userboot.fs
index dd76958..3ae899c 100644
--- a/openbios-devel/forth/admin/userboot.fs
+++ b/openbios-devel/forth/admin/userboot.fs
@@ -16,7 +16,7 @@
     execute		
   then
 
-  (encode-bootpath)	\ Setup bootpath/bootargs
+  (find-bootdevice)	\ Setup bootargs
   $load			\ load and go
   go
 ;
diff --git a/openbios-devel/forth/debugging/client.fs b/openbios-devel/forth/debugging/client.fs
index 9da9b33..e837e2a 100644
--- a/openbios-devel/forth/debugging/client.fs
+++ b/openbios-devel/forth/debugging/client.fs
@@ -59,12 +59,13 @@ variable file-size
   then
   ;
 
-: (encode-bootpath) ( param-str param-len -- bootpath-str bootpath-len)
-  \ Parse the <param> string from a load/boot command and set both
-  \ the bootargs and bootpath properties as appropriate.
+: (find-bootdevice) ( param-str param-len -- bootpath-str bootpath-len)
+  \ Parse the <param> string which is a space-separated list of one or
+  \ more potential boot devices, and return the first one that can be
+  \ successfully opened.
 
-  \ bootpath
-  bl left-split 	\ argstr argstr-len bootdevstr bootdevstr-len
+  \ Space-separated bootpath string
+  bl left-split 	\ bootpathstr bootpathstr-len bootdevstr bootdevstr-len
   dup 0= if
 
     \ None specified. As per IEEE-1275 specification, search through each value
@@ -89,12 +90,6 @@ variable file-size
     2drop
   then
 
-  \ Set the bootpath property
-  2dup encode-string
-  " /chosen" (find-dev) if
-    " bootpath" rot (property)
-  then
-
   \ bootargs
   2swap dup 0= if
     \ None specified, use default from nvram
@@ -108,6 +103,31 @@ variable file-size
   then
 ;
 
+\ Locate the boot-device opened by this ihandle (currently taken as being
+\ the first non-interposed package in the instance chain)
+
+: ihandle>boot-device-handle ( ihandle -- 0 | device-ihandle -1 )
+  >r 0
+  begin r> dup >in.my-parent @ dup >r while
+    ( result ihandle R: ihandle.parent )
+    dup >in.interposed @ 0= if
+      \ Find the first non-interposed package
+      over 0= if
+        swap drop
+      else
+        drop
+      then
+    else
+      drop
+    then
+  repeat
+  r> drop drop
+
+  dup 0<> if
+    -1
+  then
+;
+
 : $load ( devstr len )
   open-dev ( ihandle )
   dup 0= if
@@ -118,13 +138,53 @@ variable file-size
   " load-base" evaluate swap ( load-base ihandle )
   dup ihandle>phandle " load" rot find-method ( xt 0|1 )
   if swap call-package !load-size else cr ." Cannot find load for this package" 2drop then
+
+  \ If the boot device path doesn't contain an explicit partition id, e.g. cd:,\\:tbxi
+  \ then the interposed partition package may have auto-probed a suitable partition. If
+  \ this is the case then it will have set the " selected-partition-args" property in
+  \ the partition package to contain the new device arguments.
+  \
+  \ In order to ensure that bootpath contains the partition argument, we use the contents
+  \ of this property if it exists to override the boot device arguments when generating
+  \ the full bootpath using get-instance-path.
+
+  my-self
+  r@ to my-self
+  " selected-partition-args" get-inherited-property 0= if
+    decode-string 2swap 2drop
+    ( myself-save partargs-str partargs-len )
+    r@ ihandle>boot-device-handle if
+      ( myself-save partargs-str partargs-len block-ihandle )
+      \ Override the arguments before get-instance-path
+      dup >in.arguments 2@ >r >r dup >r    ( R: block-ihandle arg-len arg-str )
+      >in.arguments 2!    ( myself-save )
+      r@ " get-instance-path" $find if
+        execute   ( myself-save bootpathstr bootpathlen )
+      then
+      \ Now write the original arguments back
+      r> r> r> rot >in.arguments 2!   ( myself-save bootpathstr bootpathlen  R: )
+      rot    ( bootpathstr bootpathlen myself-save )
+    then
+  else
+    my-self " get-instance-path" $find if
+      execute  ( myself-save bootpathstr pathlen )
+      rot    ( bootpathstr bootpathlen myself-save )
+    then
+  then
+  to my-self
+
+  \ Set bootpath property in /chosen
+  encode-string " /chosen" (find-dev) if
+    " bootpath" rot (property)
+  then
+
   r> close-dev
   init-program
   ;
 
 : load    ( "{params}<cr>" -- )
   linefeed parse
-  (encode-bootpath)
+  (find-bootdevice)
   $load
 ;
 
diff --git a/openbios-devel/forth/device/property.fs b/openbios-devel/forth/device/property.fs
index d19546c..f9769fb 100644
--- a/openbios-devel/forth/device/property.fs
+++ b/openbios-devel/forth/device/property.fs
@@ -185,7 +185,7 @@
     >r >r >r          ( R: prop-addr1 prop-addr2 prop-len2 nlen )
     drop
     r> r> r>          ( nlen prop-len2 prop-addr2 )
-    -rot swap         ( prop-addr2 prop-len2 nlen )
+    -rot swap 1-      ( prop-addr2 prop-len2 nlen )
     r> swap           ( prop-addr2 prop-len2 str len )
   else
     0 0
diff --git a/openbios-devel/packages/mac-parts.c b/openbios-devel/packages/mac-parts.c
index c29b554..67d58e7 100644
--- a/openbios-devel/packages/mac-parts.c
+++ b/openbios-devel/packages/mac-parts.c
@@ -50,14 +50,14 @@ macparts_open( macparts_info_t *di )
 {
 	char *str = my_args_copy();
 	char *parstr = NULL, *argstr = NULL;
-	char *tmpstr, *bootpath;
+	char *tmpstr;
 	int bs, parnum=-1, apple_parnum=-1;
 	int parlist[2], parlist_size = 0;
 	desc_map_t dmap;
 	part_entry_t par;
 	int ret = 0, i = 0, j = 0;
 	int want_bootcode = 0;
-	phandle_t ph, chosen_ph;
+	phandle_t ph;
 	ducell offs = 0, size = -1;
 
 	DPRINTF("macparts_open '%s'\n", str );
@@ -260,35 +260,20 @@ macparts_open( macparts_info_t *di )
 	    if( ph ) {
 		    DPRINTF("mac-parts: filesystem found on partition %d with ph " FMT_ucellx " and args %s\n", parnum, ph, argstr);
 		    di->filesystem_ph = ph;
-
-		    /* Update bootpath to reflect where we booted from */
-		    chosen_ph = find_dev("/chosen");
-		    tmpstr = get_property(chosen_ph, "bootpath", &i);
-		    if (tmpstr == NULL) {
-			tmpstr = strdup("");
-		    }
 		    
-		    /* Find just the device */
-		    if (strlen(tmpstr)) {
-			for (i = 0; i < strlen(tmpstr); i++) {
-			    if (tmpstr[i] == ':' || tmpstr[i] == ',') {
-				tmpstr[i] = '\0';
-			    }
-			}
-			
-			/* Rebuild bootpath with the currently selected partition number */
-			bootpath = malloc(strlen(tmpstr) + strlen(str) + 4);
-			sprintf(bootpath, "%s:%d", tmpstr, parnum);
-			if (strlen(argstr)) {
-			    sprintf(bootpath, "%s:%d,%s", tmpstr, parnum, argstr);
-			} else {
-			    sprintf(bootpath, "%s:%d", tmpstr, parnum);
-			}
-			
-			DPRINTF("mac-parts: setting bootpath to %s\n", bootpath);
-			
-			set_property(chosen_ph, "bootpath", bootpath, strlen(bootpath) + 1);
+		    /* In case no partition was specified, set a special selected-partition-args property
+		       giving the device parameters that we can use to generate bootpath */
+		    tmpstr = malloc(strlen(argstr) + 2 + 1);
+		    if (strlen(argstr)) {
+			sprintf(tmpstr, "%d,%s", parnum, argstr);
+		    } else {
+			sprintf(tmpstr, "%d", parnum);
 		    }
+
+		    push_str(tmpstr);
+		    feval("strdup encode-string \" selected-partition-args\" property");
+
+		    free(tmpstr);
 		
 		    /* If we have been asked to open a particular file, interpose the filesystem package with 
 		    the passed filename as an argument */
-- 
1.7.10.4




More information about the OpenBIOS mailing list