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 _______________________________________________ ipxe-devel mailing list ipxe-devel@lists.ipxe.org https://lists.ipxe.org/mailman/listinfo.cgi/ipxe-devel