Boot loader arguments (was: ZFS support for EFI)

Ganael Laplanche ganael.laplanche at corp.ovh.com
Tue Aug 4 07:30:04 UTC 2015


On Monday, August 03, 2015 08:40:13 PM Ian Lepore wrote:

Hi Ian,

> It looks like your patches got scrubbed off somehow.

Yes, sorry, here they are, inline :

This one sets the environment reading argv[] :

8<--------------------------------->8
--- sys/boot/efi/loader/main.c.orig     2015-07-28 09:31:08.648856000 +0200
+++ sys/boot/efi/loader/main.c  2015-07-30 09:02:42.695337864 +0200
@@ -67,7 +67,10 @@
        char vendor[128];
        EFI_LOADED_IMAGE *img;
        EFI_GUID *guid;
-       int i;
+       int i, j;
+
+#define MAX_ARG_LEN 128
+       char var[MAX_ARG_LEN];
 
        /*
         * XXX Chicken-and-egg problem; we want to have console output
@@ -83,6 +86,17 @@
        }
 
        /*
+        * Initialize environment using argv[] after converting from UCS-2 to 
ASCII
+        */
+       for (i = 1; i < argc; i++) {
+               for(j = 0; ((char)argv[i][j] != 0) && (j < (MAX_ARG_LEN - 1)); 
j++)
+                       var[j] = (char)argv[i][j];
+               var[j] = 0;
+               putenv(var);
+               /* printf("main: added environment variable: %s\n", var); */
+       }
+
+       /*
         * March through the device switch probing for things.
         */
        for (i = 0; devsw[i] != NULL; i++)
8<--------------------------------->8

and this one overrides the BOOTP root-path if dhcp.root-path.override is set :

8<--------------------------------->8
--- lib/libstand/bootp.c.orig   2015-07-29 08:38:28.970379976 +0200
+++ lib/libstand/bootp.c        2015-07-29 09:08:59.747891922 +0200
@@ -383,8 +383,20 @@
                        bcopy(cp, &rootip.s_addr, sizeof(swapip.s_addr));
                }
                if (tag == TAG_ROOTPATH) {
-                       strncpy(rootpath, (char *)cp, sizeof(rootpath));
-                       rootpath[size] = '\0';
+                       /*
+                        * XXX Set dhcp.root-path.override to force rootpath
+                        * locally and ignore BOOTP vendor tag 17 (root-path)
+                        */
+                       char *rootpath_o = getenv("dhcp.root-path.override");
+                       if (rootpath_o == NULL) {
+                               strncpy(rootpath, (char *)cp, 
sizeof(rootpath));
+                               rootpath[size] = '\0';
+                               /* printf("vend_rfc1048: rootpath set from 
BOOTP: %s\n", rootpath); */
+                       }
+                       else {
+                               strcpy(rootpath, rootpath_o);
+                               /* printf("vend_rfc1048: rootpath set to: 
%s\n", rootpath); */
+                       }
                }
                if (tag == TAG_HOSTNAME) {
                        strncpy(hostname, (char *)cp, sizeof(hostname));
8<--------------------------------->8

Again, those patches would probably need improvements, as there is (for 
example) no sanitization done before setenv().

Anyway, this allows to chainload the loader and pass your root-path (and any 
other variable) this way (e.g. with iPXE) :

#!ipxe
chain http://path.to/loader.efi dhcp.root-
path.override=server_ip:/path/to/root some_other_var=value

> I recently tweaked loader(8) to make it easier for the data normally
> gathered from bootp/dhcp to be provided "from the environment" --
> whatever that may mean for a given flavor of loader.  The network code
> already had some provisions for setting the required variables before
> the first attempt to do network access, my changes just shuffled things
> around a bit to make it easier to parse a "rootpath" var formatted as
> "rootserverip:/path/stuff" into the existing global vars.
> 
> See r283062 for those changes, and r283066 for an example of obtaining
> the values from "somewhere" (in this case the u-boot environment) and
> setting the corresponding global vars for netbooting.

Interesting, thanks for the pointers. U-boot might be useful here, I have to 
check that.

> The comments in r283066 might be a useful guide to implementing the same
> kind of thing based on parsing an EFI command line.

Yep, that would probably be a cleaner way to go.

> It may be that my changes didn't cover all situations and more tweaking
> is needed, especially if the situation is that some data should come
> from bootp/dhcp and other data should be overridden from the command
> line.

Yes, that's *exactly* the case we are facing, where the root-path given by 
BOOTP cannot always be used :/

Best regards,

-- 
Ganaël LAPLANCHE <ganael.laplanche at corp.ovh.com>


More information about the freebsd-hackers mailing list