On Sun, Dec 11, 2016 at 2:10 AM, Christian Nilsson <nik...@gmail.com> wrote: > cmdline part is copied over from pcbios functionallity > > Signed-off-by: Christian Nilsson <nik...@gmail.com> > --- > src/config/config_efi.c | 2 + > src/include/ipxe/errfile.h | 1 + > src/interface/efi/efi_runtime.c | 177 > ++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 180 insertions(+) > create mode 100644 src/interface/efi/efi_runtime.c > > diff --git a/src/config/config_efi.c b/src/config/config_efi.c > index 92678d1..161019a 100644 > --- a/src/config/config_efi.c > +++ b/src/config/config_efi.c > @@ -49,3 +49,5 @@ REQUIRE_OBJECT ( efi_fbcon ); > #ifdef DOWNLOAD_PROTO_FILE > REQUIRE_OBJECT ( efi_local ); > #endif > + > +REQUIRE_OBJECT ( efi_runtime ); > diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h > index d0b93d0..a8ea9d1 100644 > --- a/src/include/ipxe/errfile.h > +++ b/src/include/ipxe/errfile.h > @@ -361,6 +361,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); > #define ERRFILE_efi_local ( ERRFILE_OTHER | 0x004d0000 ) > #define ERRFILE_efi_entropy ( ERRFILE_OTHER | 0x004e0000 ) > #define ERRFILE_cert_cmd ( ERRFILE_OTHER | 0x004f0000 ) > +#define ERRFILE_efi_runtime ( ERRFILE_OTHER | 0x00500000 ) > > /** @} */ > > diff --git a/src/interface/efi/efi_runtime.c b/src/interface/efi/efi_runtime.c > new file mode 100644 > index 0000000..bc7ff82 > --- /dev/null > +++ b/src/interface/efi/efi_runtime.c > @@ -0,0 +1,177 @@ > +/* > + * Copyright (C) 2011 Michael Brown <mbr...@fensystems.co.uk>. > + * > + * This program 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 2 of the > + * License, or any later version. > + * > + * This program 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 this program; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA > + * 02110-1301, USA. > + * > + * You can also choose to distribute this program under the terms of > + * the Unmodified Binary Distribution Licence (as given in the file > + * COPYING.UBDL), provided that you have satisfied its requirements. > + */ > + > +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); > + > +/** @file > + * > + * Command line passed to iPXE at runtime > + * > + */ > + > +#include <stdio.h> > +#include <stdlib.h> > +#include <ctype.h> > +#include <errno.h> > +#include <ipxe/init.h> > +#include <ipxe/image.h> > +#include <ipxe/script.h> > +#include <ipxe/efi/efi.h> > + > +/** Internal copy of the command line */ > +static char *cmdline_copy; > + > +/** Free command line image */ > +static void cmdline_image_free ( struct refcnt *refcnt ) { > + struct image *image = container_of ( refcnt, struct image, refcnt ); > + > + DBGC ( image, "RUNTIME freeing command line\n" ); > + free ( cmdline_copy ); > +} > + > +/** Embedded script representing the command line */ > +static struct image cmdline_image = { > + .refcnt = REF_INIT ( cmdline_image_free ), > + .name = "<CMDLINE>", > + .type = &script_image_type, > +}; > + > +/** Colour for debug messages */ > +#define colour &cmdline_image > + > +/** > + * Strip unwanted cruft from command line > + * > + * @v cmdline Command line > + * @v cruft Initial substring of cruft to strip > + */ > +static void cmdline_strip ( char *cmdline, const char *cruft ) { > + char *strip; > + char *strip_end; > + > + /* Find unwanted cruft, if present */ > + if ( ! ( strip = strstr ( cmdline, cruft ) ) ) > + return; > + > + /* Strip unwanted cruft */ > + strip_end = strchr ( strip, ' ' ); > + if ( strip_end ) { > + *strip_end = '\0'; > + DBGC ( colour, "RUNTIME stripping \"%s\"\n", strip ); > + strcpy ( strip, ( strip_end + 1 ) ); > + } else { > + DBGC ( colour, "RUNTIME stripping \"%s\"\n", strip ); > + *strip = '\0'; > + } > +} > + > +/** > + * Initialise command line > + * > + * @ret rc Return status code > + */ > +static int cmdline_init ( void ) { > + EFI_LOADED_IMAGE_PROTOCOL *loaded = efi_loaded_image; > + size_t cmdline_len = ( loaded->LoadOptionsSize / sizeof ( wchar_t ) ); > + char cmdline_efi[ cmdline_len + 1 /* NUL */ ]; > + const wchar_t *wcmdline = loaded->LoadOptions; > + char *cmdline; > + size_t len; > + int rc; > + > + /* Convert command line to ASCII */ > + snprintf ( cmdline_efi, sizeof ( cmdline_efi ), "%ls", wcmdline ); > + > + /* Do nothing if no command line was specified */ > + if ( ! cmdline_efi ) { > + DBGC ( colour, "RUNTIME found no command line\n" ); > + return 0; > + } > + len = ( strlen ( cmdline_efi ) + 1 /* NUL */ ); > + > + /* Allocate and copy command line */ > + cmdline_copy = malloc ( len ); > + if ( ! cmdline_copy ) { > + DBGC ( colour, "RUNTIME could not allocate %zd bytes for " > + "command line\n", len ); > + rc = -ENOMEM; > + goto err_alloc_cmdline_copy; > + } > + cmdline = cmdline_copy; > + strcpy ( cmdline, cmdline_efi ); > + DBGC ( colour, "RUNTIME found command line \"%s\"\n", > + cmdline ); > + > + /* Check for unwanted cruft in the command line */ > + while ( isspace ( *cmdline ) ) > + cmdline++; > + /* skip program name, efi always add it first */ > + while ( ! isspace ( *cmdline ) ) > + cmdline++; > + /* Strip unwanted cruft from the command line */ > + cmdline_strip ( cmdline, "BOOT_IMAGE=" ); > + cmdline_strip ( cmdline, "initrd=" ); > + while ( isspace ( *cmdline ) ) > + cmdline++; > + DBGC ( colour, "RUNTIME using command line \"%s\"\n", cmdline ); > + > + /* Prepare and register image */ > + cmdline_image.data = virt_to_user ( cmdline ); > + cmdline_image.len = strlen ( cmdline ); > + if ( cmdline_image.len ) { > + if ( ( rc = register_image ( &cmdline_image ) ) != 0 ) { > + DBGC ( colour, "RUNTIME could not register command " > + "line: %s\n", strerror ( rc ) ); > + goto err_register_image; > + } > + } > + > + /* Drop our reference to the image */ > + image_put ( &cmdline_image ); > + > + return 0; > + > + err_register_image: > + image_put ( &cmdline_image ); > + err_alloc_cmdline_copy: > + return rc; > +} > + > +/** > + * Initialise command line > + * > + */ > +static void runtime_init ( void ) { > + int rc; > + > + /* Initialise command line */ > + if ( ( rc = cmdline_init() ) != 0 ) { > + /* No way to report failure */ > + return; > + } > +} > + > +/** Command line initialisation function */ > +struct startup_fn efi_runtime_startup_fn __startup_fn ( STARTUP_NORMAL ) = { > + .startup = runtime_init, > +}; > -- > 2.0.5
Any reason why this patch was ignored? Maybe it can be done with less code duplication but the idea seems legit. It's clearly a gap in EFI functionality as compared to BIOS. Thanks, Ladi _______________________________________________ ipxe-devel mailing list ipxe-devel@lists.ipxe.org https://lists.ipxe.org/mailman/listinfo.cgi/ipxe-devel