浏览代码

[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>
tags/v1.20.1
Michael Brown 13 年前
父节点
当前提交
b2332d5118
共有 6 个文件被更改,包括 142 次插入1 次删除
  1. 113
    0
      src/arch/i386/core/cmdline.c
  2. 10
    0
      src/arch/i386/prefix/lkrnprefix.S
  3. 1
    1
      src/image/embedded.c
  4. 1
    0
      src/image/script.c
  5. 1
    0
      src/include/ipxe/init.h
  6. 16
    0
      src/include/ipxe/script.h

+ 113
- 0
src/arch/i386/core/cmdline.c 查看文件

@@ -0,0 +1,113 @@
1
+/*
2
+ * Copyright (C) 2011 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+FILE_LICENCE ( GPL2_OR_LATER );
20
+
21
+/** @file
22
+ *
23
+ * Command line passed to iPXE
24
+ *
25
+ */
26
+
27
+#include <stddef.h>
28
+#include <stdint.h>
29
+#include <stdlib.h>
30
+#include <assert.h>
31
+#include <ipxe/init.h>
32
+#include <ipxe/image.h>
33
+#include <ipxe/script.h>
34
+#include <realmode.h>
35
+
36
+/** Command line physical address
37
+ *
38
+ * This can be set by the prefix.
39
+ */
40
+uint32_t __bss16 ( cmdline_phys );
41
+#define cmdline_phys __use_data16 ( cmdline_phys )
42
+
43
+/** Internal copy of the command line */
44
+static char *cmdline_copy;
45
+
46
+/** Free command line image */
47
+static void cmdline_image_free ( struct refcnt *refcnt ) {
48
+	struct image *image = container_of ( refcnt, struct image, refcnt );
49
+
50
+	DBGC ( image, "CMDLINE freeing command line\n" );
51
+	free ( cmdline_copy );
52
+}
53
+
54
+/** Embedded script representing the command line */
55
+static struct image cmdline_image = {
56
+	.refcnt = REF_INIT ( cmdline_image_free ),
57
+	.name = "<CMDLINE>",
58
+	.type = &script_image_type,
59
+};
60
+
61
+/**
62
+ * Initialise command line
63
+ *
64
+ */
65
+static void cmdline_init ( void ) {
66
+	struct image *image = &cmdline_image;
67
+	userptr_t cmdline_user;
68
+	char *cmdline;
69
+	char *tmp;
70
+	size_t len;
71
+
72
+	/* Do nothing if no command line was specified */
73
+	if ( ! cmdline_phys ) {
74
+		DBGC ( image, "CMDLINE found no command line\n" );
75
+		return;
76
+	}
77
+	cmdline_user = phys_to_user ( cmdline_phys );
78
+	len = ( strlen_user ( cmdline_user, 0 ) + 1 /* NUL */ );
79
+
80
+	/* Allocate and copy command line */
81
+	cmdline_copy = malloc ( len );
82
+	if ( ! cmdline_copy ) {
83
+		DBGC ( image, "CMDLINE could not allocate %zd bytes\n", len );
84
+		/* No way to indicate failure */
85
+		return;
86
+	}
87
+	cmdline = cmdline_copy;
88
+	copy_from_user ( cmdline, cmdline_user, 0, len );
89
+	DBGC ( image, "CMDLINE found \"%s\"\n", cmdline );
90
+
91
+	/* Check for unwanted cruft in the command line */
92
+	while ( isspace ( *cmdline ) )
93
+		cmdline++;
94
+	if ( ( tmp = strstr ( cmdline, "BOOT_IMAGE=" ) ) != NULL ) {
95
+		DBGC ( image, "CMDLINE stripping \"%s\"\n", tmp );
96
+		*tmp = '\0';
97
+	}
98
+	DBGC ( image, "CMDLINE using \"%s\"\n", cmdline );
99
+
100
+	/* Prepare and register image */
101
+	cmdline_image.data = virt_to_user ( cmdline );
102
+	cmdline_image.len = strlen ( cmdline );
103
+	if ( cmdline_image.len )
104
+		register_image ( &cmdline_image );
105
+
106
+	/* Drop our reference to the image */
107
+	image_put ( &cmdline_image );
108
+}
109
+
110
+/** Command line initialisation function */
111
+struct init_fn cmdline_init_fn __init_fn ( INIT_NORMAL ) = {
112
+	.initialise = cmdline_init,
113
+};

+ 10
- 0
src/arch/i386/prefix/lkrnprefix.S 查看文件

@@ -193,6 +193,9 @@ run_ipxe:
193 193
 	movw	%ax, %ss
194 194
 	movw	$0x7c00, %sp
195 195
 
196
+	/* Retrieve command-line pointer */
197
+	movl	%es:cmd_line_ptr, %edx
198
+
196 199
 	/* Install iPXE */
197 200
 	call	install
198 201
 
@@ -206,6 +209,13 @@ run_ipxe:
206 209
 	lret
207 210
 	.section ".text16", "awx", @progbits
208 211
 1:
212
+	/* Set up %ds for access to .data16 */
213
+	movw	%bx, %ds
214
+
215
+	/* Store command-line pointer */
216
+	movl	%edx, cmdline_phys
217
+
218
+	/* Run iPXE */
209 219
 	pushl	$main
210 220
 	pushw	%cs
211 221
 	call	prot_call

+ 1
- 1
src/image/embedded.c 查看文件

@@ -86,6 +86,6 @@ static void embedded_init ( void ) {
86 86
 }
87 87
 
88 88
 /** Embedded image initialisation function */
89
-struct init_fn embedded_init_fn __init_fn ( INIT_NORMAL ) = {
89
+struct init_fn embedded_init_fn __init_fn ( INIT_LATE ) = {
90 90
 	.initialise = embedded_init,
91 91
 };

+ 1
- 0
src/image/script.c 查看文件

@@ -36,6 +36,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
36 36
 #include <ipxe/image.h>
37 37
 #include <ipxe/shell.h>
38 38
 #include <usr/prompt.h>
39
+#include <ipxe/script.h>
39 40
 
40 41
 /** Currently running script
41 42
  *

+ 1
- 0
src/include/ipxe/init.h 查看文件

@@ -29,6 +29,7 @@ struct init_fn {
29 29
 #define INIT_SERIAL	02	/**< Serial driver initialisation */
30 30
 #define	INIT_CONSOLE	03	/**< Console initialisation */
31 31
 #define INIT_NORMAL	04	/**< Normal initialisation */
32
+#define INIT_LATE	05	/**< Late initialisation */
32 33
 
33 34
 /** @} */
34 35
 

+ 16
- 0
src/include/ipxe/script.h 查看文件

@@ -0,0 +1,16 @@
1
+#ifndef _IPXE_SCRIPT_H
2
+#define _IPXE_SCRIPT_H
3
+
4
+/** @file
5
+ *
6
+ * iPXE scripts
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER );
11
+
12
+#include <ipxe/image.h>
13
+
14
+extern struct image_type script_image_type __image_type ( PROBE_NORMAL );
15
+
16
+#endif /* _IPXE_SCRIPT_H */

正在加载...
取消
保存