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@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 */