summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brown2011-03-07 23:02:07 +0100
committerMichael Brown2011-03-07 23:28:31 +0100
commitb2332d511807b87bd71cf73acaaf48e671d71c9d (patch)
treefde829da1d96d26c6d1047c0a41cc2aa8558df1c /src
parent[main] Remove shell prompt when using an embedded image (diff)
downloadipxe-b2332d511807b87bd71cf73acaaf48e671d71c9d.tar.gz
ipxe-b2332d511807b87bd71cf73acaaf48e671d71c9d.tar.xz
ipxe-b2332d511807b87bd71cf73acaaf48e671d71c9d.zip
[prefix] Allow iPXE's own command line to be executed as a script
Some prefixes (e.g. .lkrn) allow a command line to be passed in to iPXE. At present, this command line is ignored. If a command line is provided, treat it as an embedded script (without an explicit "#!ipxe" magic marker). This allows for patterns of invocation such as title iPXE kernel /boot/ipxe.lkrn dhcp && \ sanboot iscsi:10.0.4.1::::iqn.2010-04.org.ipxe.dolphin:storage Here GRUB is instructed to load ipxe.lkrn with an embedded script equivalent to #!ipxe dhcp sanboot iscsi:10.0.4.1::::iqn.2010-04.org.ipxe.dolphin:storage This can be used to effectively vary the embedded script without having to rebuild ipxe.lkrn. Originally-implemented-by: Dave Hansen <dave@sr71.net> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src')
-rw-r--r--src/arch/i386/core/cmdline.c113
-rw-r--r--src/arch/i386/prefix/lkrnprefix.S10
-rw-r--r--src/image/embedded.c2
-rw-r--r--src/image/script.c1
-rw-r--r--src/include/ipxe/init.h1
-rw-r--r--src/include/ipxe/script.h16
6 files changed, 142 insertions, 1 deletions
diff --git a/src/arch/i386/core/cmdline.c b/src/arch/i386/core/cmdline.c
new file mode 100644
index 00000000..fa5adb8c
--- /dev/null
+++ b/src/arch/i386/core/cmdline.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2011 Michael Brown <mbrown@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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * Command line passed to iPXE
+ *
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <ipxe/init.h>
+#include <ipxe/image.h>
+#include <ipxe/script.h>
+#include <realmode.h>
+
+/** Command line physical address
+ *
+ * This can be set by the prefix.
+ */
+uint32_t __bss16 ( cmdline_phys );
+#define cmdline_phys __use_data16 ( cmdline_phys )
+
+/** 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, "CMDLINE 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,
+};
+
+/**
+ * Initialise command line
+ *
+ */
+static void cmdline_init ( void ) {
+ struct image *image = &cmdline_image;
+ userptr_t cmdline_user;
+ char *cmdline;
+ char *tmp;
+ size_t len;
+
+ /* Do nothing if no command line was specified */
+ if ( ! cmdline_phys ) {
+ DBGC ( image, "CMDLINE found no command line\n" );
+ return;
+ }
+ cmdline_user = phys_to_user ( cmdline_phys );
+ len = ( strlen_user ( cmdline_user, 0 ) + 1 /* NUL */ );
+
+ /* Allocate and copy command line */
+ cmdline_copy = malloc ( len );
+ if ( ! cmdline_copy ) {
+ DBGC ( image, "CMDLINE could not allocate %zd bytes\n", len );
+ /* No way to indicate failure */
+ return;
+ }
+ cmdline = cmdline_copy;
+ copy_from_user ( cmdline, cmdline_user, 0, len );
+ DBGC ( image, "CMDLINE found \"%s\"\n", cmdline );
+
+ /* Check for unwanted cruft in the command line */
+ while ( isspace ( *cmdline ) )
+ cmdline++;
+ if ( ( tmp = strstr ( cmdline, "BOOT_IMAGE=" ) ) != NULL ) {
+ DBGC ( image, "CMDLINE stripping \"%s\"\n", tmp );
+ *tmp = '\0';
+ }
+ DBGC ( image, "CMDLINE using \"%s\"\n", cmdline );
+
+ /* Prepare and register image */
+ cmdline_image.data = virt_to_user ( cmdline );
+ cmdline_image.len = strlen ( cmdline );
+ if ( cmdline_image.len )
+ register_image ( &cmdline_image );
+
+ /* Drop our reference to the image */
+ image_put ( &cmdline_image );
+}
+
+/** Command line initialisation function */
+struct init_fn cmdline_init_fn __init_fn ( INIT_NORMAL ) = {
+ .initialise = cmdline_init,
+};
diff --git a/src/arch/i386/prefix/lkrnprefix.S b/src/arch/i386/prefix/lkrnprefix.S
index 008c79ef..f87ef85a 100644
--- a/src/arch/i386/prefix/lkrnprefix.S
+++ b/src/arch/i386/prefix/lkrnprefix.S
@@ -193,6 +193,9 @@ run_ipxe:
movw %ax, %ss
movw $0x7c00, %sp
+ /* Retrieve command-line pointer */
+ movl %es:cmd_line_ptr, %edx
+
/* Install iPXE */
call install
@@ -206,6 +209,13 @@ run_ipxe:
lret
.section ".text16", "awx", @progbits
1:
+ /* Set up %ds for access to .data16 */
+ movw %bx, %ds
+
+ /* Store command-line pointer */
+ movl %edx, cmdline_phys
+
+ /* Run iPXE */
pushl $main
pushw %cs
call prot_call
diff --git a/src/image/embedded.c b/src/image/embedded.c
index 2ddccfed..6358378f 100644
--- a/src/image/embedded.c
+++ b/src/image/embedded.c
@@ -86,6 +86,6 @@ static void embedded_init ( void ) {
}
/** Embedded image initialisation function */
-struct init_fn embedded_init_fn __init_fn ( INIT_NORMAL ) = {
+struct init_fn embedded_init_fn __init_fn ( INIT_LATE ) = {
.initialise = embedded_init,
};
diff --git a/src/image/script.c b/src/image/script.c
index b819693d..572eac71 100644
--- a/src/image/script.c
+++ b/src/image/script.c
@@ -36,6 +36,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/image.h>
#include <ipxe/shell.h>
#include <usr/prompt.h>
+#include <ipxe/script.h>
/** Currently running script
*
diff --git a/src/include/ipxe/init.h b/src/include/ipxe/init.h
index 954cda45..19c5925b 100644
--- a/src/include/ipxe/init.h
+++ b/src/include/ipxe/init.h
@@ -29,6 +29,7 @@ struct init_fn {
#define INIT_SERIAL 02 /**< Serial driver initialisation */
#define INIT_CONSOLE 03 /**< Console initialisation */
#define INIT_NORMAL 04 /**< Normal initialisation */
+#define INIT_LATE 05 /**< Late initialisation */
/** @} */
diff --git a/src/include/ipxe/script.h b/src/include/ipxe/script.h
new file mode 100644
index 00000000..33420dae
--- /dev/null
+++ b/src/include/ipxe/script.h
@@ -0,0 +1,16 @@
+#ifndef _IPXE_SCRIPT_H
+#define _IPXE_SCRIPT_H
+
+/** @file
+ *
+ * iPXE scripts
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <ipxe/image.h>
+
+extern struct image_type script_image_type __image_type ( PROBE_NORMAL );
+
+#endif /* _IPXE_SCRIPT_H */