----- Original Message ----- > From: Andrey Borzenkov <arvidj...@gmail.com> > To: Rigoberto Corujo <rcor...@yahoo.com> > Cc: "help-g...@gnu.org" <help-g...@gnu.org>; grub-devel@gnu.org > Sent: Wednesday, May 1, 2013 10:59 AM > Subject: Re: Obtaining the MAC address of the boot NIC for a PXE boot > > В Mon, 29 Apr 2013 05:55:32 -0700 (PDT) > Rigoberto Corujo <rcor...@yahoo.com> пишет: > >> Hello everyone, >> >> With pxelinux, you can specify "IPAPPEND 2" in your boot loader > configuration file and the MAC address of the boot NIC automatically gets > appended to your kernel parameters as "BOOTIF=XX:XX:XX:XX:XX:XX". >> >> I am now trying to become familiar with Grub 2, because if its EFI support. > I noticed that with Grub 2, some of the documentation, which may be > outdated, > says that there is a "net_pxe_mac" variable which, as I understand it, > should contain the MAC address of the boot NIC. However, I've built the > latest Grub 2 sources and, when I PXE boot and drop into a grub shell prompt, > if > type "set", I don't see "net_pxe_mac" listed as one of > the variables. I know there is a "net_ls_addr" command which prints > out something like "efinet8 3c:4a:92:b2:6a:e8 10.1.1.114", but I > don't know how to use Grub scripting to parse out the MAC address. I also > don't know if there will ever be a case where "net_ls_addr" will > print out multiple entries on a PXE boot, making it difficult to determine > which > one corresponds to the boot NIC. >> >> >> Basically, I'm using the "ksdevice=bootif" kernel parameter > when PXE booting my Red Hat kernel. With PXE Linux, "bootif" provides > the MAC address of the boot NIC. I was hoping to do something like > "ksdevice=${net_pxe_mac}", but since "net_pxe_mac" does not > appear to be getting set, I need to find some other method. >> > > > As it stands currently, net_pxe_* variables are defined on PC BIOS > platform only. For UEFI (which you apparently have) GRUB2 defines > net_efinetNN_* variables where efinetNN is symbolic name for interface > that was used to boot GRUB2. > > May be GRUB2 should also define net_pxe_* namespace for the case of > UEFI. There is no real way to find out which interface was used for > booting and even if there were, grub does not support nested > variables substitution or eval'ing (like ${net_${boot_if}_mac). > > Probably, adding "eval" support is really the most simple. Could you > test the patch below. What it does, is > > - it adds "eval" command (same as known from UNIX shells) which > executes its argument > > - it exports boot interface as "efi_boot_interface" variable > > This should allow you to do > > if $grub_platform = efi ; then > eval "set net_pxe_mac=\$net_${efi_boot_interface}_mac" > fi > > and then use $net_pxe_mac on both platforms. > > If it works for you, I will clean it up; for consistency this is > probably needed for ieee1275 as well. > > --- > grub-core/Makefile.core.def | 5 ++++ > grub-core/commands/eval.c | 51 ++++++++++++++++++++++++++++++++++++++ > grub-core/net/drivers/efi/efinet.c | 2 ++ > 3 files changed, 58 insertions(+) > > diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def > index 7e19acb..8844f2f 100644 > --- a/grub-core/Makefile.core.def > +++ b/grub-core/Makefile.core.def > @@ -699,6 +699,11 @@ module = { > }; > > module = { > + name = eval; > + common = commands/eval.c; > +}; > + > +module = { > name = extcmd; > common = commands/extcmd.c; > common = lib/arg.c; > diff --git a/grub-core/commands/eval.c b/grub-core/commands/eval.c > new file mode 100644 > index 0000000..a21ff89 > --- /dev/null > +++ b/grub-core/commands/eval.c > @@ -0,0 +1,51 @@ > +/* > + * GRUB -- GRand Unified Bootloader > + * Copyright (C) 2009 Free Software Foundation, Inc. > + * > + * GRUB is free software: you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation, either version 3 of the License, or > + * (at your option) any later version. > + * > + * GRUB is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#include <grub/dl.h> > +#include <grub/misc.h> > +#include <grub/extcmd.h> > +#include <grub/i18n.h> > +#include <grub/term.h> > + > +GRUB_MOD_LICENSE ("GPLv3+"); > + > +static grub_err_t > +grub_cmd_eval (grub_extcmd_context_t ctxt __attribute__((__unused__)), > + int argc, char *argv[]) > +{ > + char *dummy[1] = { NULL }; > + > + if (argc != 1) > + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument > expected")); > + return grub_script_execute_sourcecode (argv[0], 0, dummy); > +} > + > +static grub_extcmd_t cmd; > + > +GRUB_MOD_INIT(eval) > +{ > + cmd = grub_register_extcmd ("eval", grub_cmd_eval, 0, > + N_("[STRING]"), N_("Evaluate commands"), > + NULL); > +} > + > +GRUB_MOD_FINI(eval) > +{ > + grub_unregister_extcmd (cmd); > +} > + > diff --git a/grub-core/net/drivers/efi/efinet.c > b/grub-core/net/drivers/efi/efinet.c > index 2b344d6..f7d8fd5 100644 > --- a/grub-core/net/drivers/efi/efinet.c > +++ b/grub-core/net/drivers/efi/efinet.c > @@ -23,6 +23,7 @@ > #include <grub/efi/api.h> > #include <grub/efi/efi.h> > #include <grub/i18n.h> > +#include <grub/env.h> > > GRUB_MOD_LICENSE ("GPLv3+"); > > @@ -250,6 +251,7 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char > **device, > &pxe_mode->dhcp_ack, > sizeof (pxe_mode->dhcp_ack), > 1, device, path); > + grub_env_set ("efi_boot_interface", card->name); > return; > } > } > -- > tg: (93daf86..) e/uefi_pxe_vars (depends on: master) > > > _______________________________________________ > Help-grub mailing list > help-g...@gnu.org > https://lists.gnu.org/mailman/listinfo/help-grub >
Thank you very much, Andrey. This worked. I did have to add the following lines to "grub-core/Makefile.core.am" to get a "eval.mod" generated, but I'm sure that it's probably because I missed an important step that would have automatically generated it. if COND_x86_64_efi platform_PROGRAMS += eval.module MODULE_FILES += eval.module$(EXEEXT) eval_module_SOURCES = commands/eval.c ## platform sources nodist_eval_module_SOURCES = ## platform nodist sources eval_module_LDADD = eval_module_CFLAGS = $(AM_CFLAGS) $(CFLAGS_MODULE) eval_module_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS_MODULE) eval_module_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS_MODULE) eval_module_CCASFLAGS = $(AM_CCASFLAGS) $(CCASFLAGS_MODULE) EXTRA_DIST += BUILT_SOURCES += $(nodist_eval_module_SOURCES) CLEANFILES += $(nodist_eval_module_SOURCES) MOD_FILES += eval.mod MARKER_FILES += eval.marker CLEANFILES += eval.marker eval.marker: $(eval_module_SOURCES) $(nodist_eval_module_SOURCES) $(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(eval_module_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1) grep 'MARKER' $@.new > $@; rm -f $@.new endif Anyway, thank you once again. Rigoberto _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel