Browse Source

[prefix] Allow an initrd to be passed to iPXE

Allow an initrd (such as an embedded script) to be passed to iPXE when
loaded as a .lkrn (or .iso) image.  This allows an embedded script to
be varied without recompiling iPXE.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
27fdb95572

+ 0
- 123
src/arch/i386/core/cmdline.c View File

@@ -1,123 +0,0 @@
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 *boot_image;
70
-	char *boot_image_end;
71
-	size_t len;
72
-
73
-	/* Do nothing if no command line was specified */
74
-	if ( ! cmdline_phys ) {
75
-		DBGC ( image, "CMDLINE found no command line\n" );
76
-		return;
77
-	}
78
-	cmdline_user = phys_to_user ( cmdline_phys );
79
-	len = ( strlen_user ( cmdline_user, 0 ) + 1 /* NUL */ );
80
-
81
-	/* Allocate and copy command line */
82
-	cmdline_copy = malloc ( len );
83
-	if ( ! cmdline_copy ) {
84
-		DBGC ( image, "CMDLINE could not allocate %zd bytes\n", len );
85
-		/* No way to indicate failure */
86
-		return;
87
-	}
88
-	cmdline = cmdline_copy;
89
-	copy_from_user ( cmdline, cmdline_user, 0, len );
90
-	DBGC ( image, "CMDLINE found \"%s\"\n", cmdline );
91
-
92
-	/* Check for unwanted cruft in the command line */
93
-	while ( isspace ( *cmdline ) )
94
-		cmdline++;
95
-	if ( ( boot_image = strstr ( cmdline, "BOOT_IMAGE=" ) ) != NULL ) {
96
-		boot_image_end = strchr ( boot_image, ' ' );
97
-		if ( boot_image_end ) {
98
-			*boot_image_end = '\0';
99
-			DBGC ( image, "CMDLINE stripping \"%s\"\n",
100
-			       boot_image );
101
-			strcpy ( boot_image, ( boot_image_end + 1 ) );
102
-		} else {
103
-			DBGC ( image, "CMDLINE stripping \"%s\"\n",
104
-			       boot_image );
105
-			*boot_image = '\0';
106
-		}
107
-	}
108
-	DBGC ( image, "CMDLINE using \"%s\"\n", cmdline );
109
-
110
-	/* Prepare and register image */
111
-	cmdline_image.data = virt_to_user ( cmdline );
112
-	cmdline_image.len = strlen ( cmdline );
113
-	if ( cmdline_image.len )
114
-		register_image ( &cmdline_image );
115
-
116
-	/* Drop our reference to the image */
117
-	image_put ( &cmdline_image );
118
-}
119
-
120
-/** Command line initialisation function */
121
-struct init_fn cmdline_init_fn __init_fn ( INIT_NORMAL ) = {
122
-	.initialise = cmdline_init,
123
-};

+ 249
- 0
src/arch/i386/core/runtime.c View File

@@ -0,0 +1,249 @@
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 and initrd passed to iPXE at runtime
24
+ *
25
+ */
26
+
27
+#include <stddef.h>
28
+#include <stdint.h>
29
+#include <stdlib.h>
30
+#include <errno.h>
31
+#include <assert.h>
32
+#include <ipxe/init.h>
33
+#include <ipxe/image.h>
34
+#include <ipxe/script.h>
35
+#include <ipxe/umalloc.h>
36
+#include <realmode.h>
37
+
38
+/** Command line physical address
39
+ *
40
+ * This can be set by the prefix.
41
+ */
42
+uint32_t __bss16 ( cmdline_phys );
43
+#define cmdline_phys __use_data16 ( cmdline_phys )
44
+
45
+/** initrd physical address
46
+ *
47
+ * This can be set by the prefix.
48
+ */
49
+uint32_t __bss16 ( initrd_phys );
50
+#define initrd_phys __use_data16 ( initrd_phys )
51
+
52
+/** initrd length
53
+ *
54
+ * This can be set by the prefix.
55
+ */
56
+uint32_t __bss16 ( initrd_len );
57
+#define initrd_len __use_data16 ( initrd_len )
58
+
59
+/** Internal copy of the command line */
60
+static char *cmdline_copy;
61
+
62
+/** Free command line image */
63
+static void cmdline_image_free ( struct refcnt *refcnt ) {
64
+	struct image *image = container_of ( refcnt, struct image, refcnt );
65
+
66
+	DBGC ( image, "RUNTIME freeing command line\n" );
67
+	free ( cmdline_copy );
68
+}
69
+
70
+/** Embedded script representing the command line */
71
+static struct image cmdline_image = {
72
+	.refcnt = REF_INIT ( cmdline_image_free ),
73
+	.name = "<CMDLINE>",
74
+	.type = &script_image_type,
75
+};
76
+
77
+/** Colour for debug messages */
78
+#define colour &cmdline_image
79
+
80
+/**
81
+ * Strip unwanted cruft from command line
82
+ *
83
+ * @v cmdline		Command line
84
+ * @v cruft		Initial substring of cruft to strip
85
+ */
86
+static void cmdline_strip ( char *cmdline, const char *cruft ) {
87
+	char *strip;
88
+	char *strip_end;
89
+
90
+	/* Find unwanted cruft, if present */
91
+	if ( ! ( strip = strstr ( cmdline, cruft ) ) )
92
+		return;
93
+
94
+	/* Strip unwanted cruft */
95
+	strip_end = strchr ( strip, ' ' );
96
+	if ( strip_end ) {
97
+		*strip_end = '\0';
98
+		DBGC ( colour, "RUNTIME stripping \"%s\"\n", strip );
99
+		strcpy ( strip, ( strip_end + 1 ) );
100
+	} else {
101
+		DBGC ( colour, "RUNTIME stripping \"%s\"\n", strip );
102
+		*strip = '\0';
103
+	}
104
+}
105
+
106
+/**
107
+ * Initialise command line
108
+ *
109
+ * @ret rc		Return status code
110
+ */
111
+static int cmdline_init ( void ) {
112
+	userptr_t cmdline_user;
113
+	char *cmdline;
114
+	size_t len;
115
+	int rc;
116
+
117
+	/* Do nothing if no command line was specified */
118
+	if ( ! cmdline_phys ) {
119
+		DBGC ( colour, "RUNTIME found no command line\n" );
120
+		return 0;
121
+	}
122
+	cmdline_user = phys_to_user ( cmdline_phys );
123
+	len = ( strlen_user ( cmdline_user, 0 ) + 1 /* NUL */ );
124
+
125
+	/* Allocate and copy command line */
126
+	cmdline_copy = malloc ( len );
127
+	if ( ! cmdline_copy ) {
128
+		DBGC ( colour, "RUNTIME could not allocate %zd bytes for "
129
+		       "command line\n", len );
130
+		rc = -ENOMEM;
131
+		goto err_alloc_cmdline_copy;
132
+	}
133
+	cmdline = cmdline_copy;
134
+	copy_from_user ( cmdline, cmdline_user, 0, len );
135
+	DBGC ( colour, "RUNTIME found command line \"%s\"\n", cmdline );
136
+
137
+	/* Strip unwanted cruft from the command line */
138
+	cmdline_strip ( cmdline, "BOOT_IMAGE=" );
139
+	cmdline_strip ( cmdline, "initrd=" );
140
+	while ( isspace ( *cmdline ) )
141
+		cmdline++;
142
+	DBGC ( colour, "RUNTIME using command line \"%s\"\n", cmdline );
143
+
144
+	/* Prepare and register image */
145
+	cmdline_image.data = virt_to_user ( cmdline );
146
+	cmdline_image.len = strlen ( cmdline );
147
+	if ( cmdline_image.len ) {
148
+		if ( ( rc = register_image ( &cmdline_image ) ) != 0 ) {
149
+			DBGC ( colour, "RUNTIME could not register command "
150
+			       "line: %s\n", strerror ( rc ) );
151
+			goto err_register_image;
152
+		}
153
+	}
154
+
155
+	/* Drop our reference to the image */
156
+	image_put ( &cmdline_image );
157
+
158
+	return 0;
159
+
160
+ err_register_image:
161
+	image_put ( &cmdline_image );
162
+ err_alloc_cmdline_copy:
163
+	return rc;
164
+}
165
+
166
+/**
167
+ * Initialise initrd
168
+ *
169
+ * @ret rc		Return status code
170
+ */
171
+static int initrd_init ( void ) {
172
+	struct image *image;
173
+	int rc;
174
+
175
+	/* Do nothing if no initrd was specified */
176
+	if ( ! initrd_phys ) {
177
+		DBGC ( colour, "RUNTIME found no initrd\n" );
178
+		return 0;
179
+	}
180
+	if ( ! initrd_len ) {
181
+		DBGC ( colour, "RUNTIME found empty initrd\n" );
182
+		return 0;
183
+	}
184
+	DBGC ( colour, "RUNTIME found initrd at [%x,%x)\n",
185
+	       initrd_phys, ( initrd_phys + initrd_len ) );
186
+
187
+	/* Allocate image */
188
+	image = alloc_image();
189
+	if ( ! image ) {
190
+		DBGC ( colour, "RUNTIME could not allocate image for "
191
+		       "initrd\n" );
192
+		goto err_alloc_image;
193
+	}
194
+	image_set_name ( image, "<INITRD>" );
195
+
196
+	/* Allocate and copy initrd content */
197
+	image->data = umalloc ( initrd_len );
198
+	if ( ! image->data ) {
199
+		DBGC ( colour, "RUNTIME could not allocate %zd bytes for "
200
+		       "initrd\n", initrd_len );
201
+		goto err_umalloc;
202
+	}
203
+	image->len = initrd_len;
204
+	memcpy_user ( image->data, 0, phys_to_user ( initrd_phys ), 0,
205
+		      initrd_len );
206
+
207
+	/* Register image */
208
+	if ( ( rc = register_image ( image ) ) != 0 ) {
209
+		DBGC ( colour, "RUNTIME could not register initrd: %s\n",
210
+		       strerror ( rc ) );
211
+		goto err_register_image;
212
+	}
213
+
214
+	/* Drop our reference to the image */
215
+	image_put ( image );
216
+
217
+	return 0;
218
+
219
+ err_register_image:
220
+ err_umalloc:
221
+	image_put ( image );
222
+ err_alloc_image:
223
+	return rc;
224
+}
225
+
226
+/**
227
+ * Initialise command line and initrd
228
+ *
229
+ */
230
+static void runtime_init ( void ) {
231
+	int rc;
232
+
233
+	/* Initialise command line */
234
+	if ( ( rc = cmdline_init() ) != 0 ) {
235
+		/* No way to report failure */
236
+		return;
237
+	}
238
+
239
+	/* Initialise initrd */
240
+	if ( ( rc = initrd_init() ) != 0 ) {
241
+		/* No way to report failure */
242
+		return;
243
+	}
244
+}
245
+
246
+/** Command line and initrd initialisation function */
247
+struct init_fn runtime_init_fn __init_fn ( INIT_NORMAL ) = {
248
+	.initialise = runtime_init,
249
+};

+ 1
- 0
src/arch/i386/include/bits/errfile.h View File

@@ -15,6 +15,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
15 15
 #define ERRFILE_biosint		( ERRFILE_ARCH | ERRFILE_CORE | 0x00040000 )
16 16
 #define ERRFILE_int13		( ERRFILE_ARCH | ERRFILE_CORE | 0x00050000 )
17 17
 #define ERRFILE_pxeparent	( ERRFILE_ARCH | ERRFILE_CORE | 0x00060000 )
18
+#define ERRFILE_runtime		( ERRFILE_ARCH | ERRFILE_CORE | 0x00070000 )
18 19
 
19 20
 #define ERRFILE_bootsector     ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00000000 )
20 21
 #define ERRFILE_bzimage	       ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00010000 )

+ 12
- 1
src/arch/i386/prefix/lkrnprefix.S View File

@@ -196,8 +196,15 @@ run_ipxe:
196 196
 	/* Retrieve command-line pointer */
197 197
 	movl	%es:cmd_line_ptr, %edx
198 198
 
199
+	/* Retrieve initrd pointer and size */
200
+	movl	%es:ramdisk_image, %ebp
201
+	movl	%es:ramdisk_size, %ecx
202
+
199 203
 	/* Install iPXE */
200
-	call	install
204
+	call	alloc_basemem
205
+	xorl	%esi, %esi
206
+	xorl	%edi, %edi
207
+	call	install_prealloc
201 208
 
202 209
 	/* Set up real-mode stack */
203 210
 	movw	%bx, %ss
@@ -215,6 +222,10 @@ run_ipxe:
215 222
 	/* Store command-line pointer */
216 223
 	movl	%edx, cmdline_phys
217 224
 
225
+	/* Store initrd pointer and size */
226
+	movl	%ebp, initrd_phys
227
+	movl	%ecx, initrd_len
228
+
218 229
 	/* Run iPXE */
219 230
 	pushl	$main
220 231
 	pushw	%cs

Loading…
Cancel
Save