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