Browse Source

Copy command line at execution time rather than load time.

Parse command line for "vga=" and "mem=" parameters
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
8a490146bf
2 changed files with 144 additions and 35 deletions
  1. 132
    35
      src/arch/i386/image/bzimage.c
  2. 12
    0
      src/arch/i386/include/bzimage.h

+ 132
- 35
src/arch/i386/image/bzimage.c View File

23
  *
23
  *
24
  */
24
  */
25
 
25
 
26
+#include <stdint.h>
27
+#include <stdlib.h>
28
+#include <string.h>
26
 #include <errno.h>
29
 #include <errno.h>
27
 #include <assert.h>
30
 #include <assert.h>
28
 #include <realmode.h>
31
 #include <realmode.h>
61
  * bzImage execution context
64
  * bzImage execution context
62
  */
65
  */
63
 struct bzimage_exec_context {
66
 struct bzimage_exec_context {
64
-	/** Kernel real-mode data segment */
65
-	uint16_t kernel_seg;
66
-	/** Kernel real-mode stack pointer */
67
-	uint16_t stack;
67
+	/** Real-mode kernel portion load segment address */
68
+	unsigned int rm_kernel_seg;
69
+	/** Real-mode kernel portion load address */
70
+	userptr_t rm_kernel;
71
+	/** Real-mode heap top (offset from rm_kernel) */
72
+	size_t rm_heap;
73
+	/** Command line (offset from rm_kernel) */
74
+	size_t rm_cmdline;
75
+	/** Video mode */
76
+	unsigned int vid_mode;
77
+	/** Memory limit */
78
+	uint64_t mem_limit;
68
 };
79
 };
69
 
80
 
81
+/**
82
+ * Parse kernel command line for bootloader parameters
83
+ *
84
+ * @v image		bzImage file
85
+ * @v exec_ctx		Execution context
86
+ * @v cmdline		Kernel command line
87
+ * @ret rc		Return status code
88
+ */
89
+static int bzimage_parse_cmdline ( struct image *image,
90
+				   struct bzimage_exec_context *exec_ctx,
91
+				   const char *cmdline ) {
92
+	char *vga;
93
+	char *mem;
94
+
95
+	/* Look for "vga=" */
96
+	if ( ( vga = strstr ( cmdline, "vga=" ) ) ) {
97
+		vga += 4;
98
+		if ( strcmp ( vga, "normal" ) == 0 ) {
99
+			exec_ctx->vid_mode = BZI_VID_MODE_NORMAL;
100
+		} else if ( strcmp ( vga, "ext" ) == 0 ) {
101
+			exec_ctx->vid_mode = BZI_VID_MODE_EXT;
102
+		} else if ( strcmp ( vga, "ask" ) == 0 ) {
103
+			exec_ctx->vid_mode = BZI_VID_MODE_ASK;
104
+		} else {
105
+			exec_ctx->vid_mode = strtoul ( vga, &vga, 16 );
106
+			if ( *vga && ( *vga != ' ' ) ) {
107
+				DBGC ( image, "bzImage %p strange \"vga=\"\n",
108
+				       image );
109
+			}
110
+		}
111
+	}
112
+
113
+	/* Look for "mem=" */
114
+	if ( ( mem = strstr ( cmdline, "mem=" ) ) ) {
115
+		mem += 4;
116
+		exec_ctx->mem_limit = strtoul ( mem, &mem, 0 );
117
+		switch ( *mem ) {
118
+		case 'G':
119
+			exec_ctx->mem_limit <<= 10;
120
+		case 'M':
121
+			exec_ctx->mem_limit <<= 10;
122
+		case 'K':
123
+			exec_ctx->mem_limit <<= 10;
124
+			break;
125
+		case '\0':
126
+		case ' ':
127
+			break;
128
+		default:
129
+			DBGC ( image, "bzImage %p strange \"mem=\"\n",
130
+			       image );
131
+			break;
132
+		}
133
+	}
134
+
135
+	return 0;
136
+}
137
+
138
+/**
139
+ * Set command line
140
+ *
141
+ * @v image		bzImage image
142
+ * @v exec_ctx		Execution context
143
+ * @v cmdline		Kernel command line
144
+ * @ret rc		Return status code
145
+ */
146
+static int bzimage_set_cmdline ( struct image *image,
147
+				 struct bzimage_exec_context *exec_ctx,
148
+				 const char *cmdline ) {
149
+	size_t cmdline_len;
150
+
151
+	/* Copy command line down to real-mode portion */
152
+	cmdline_len = ( strlen ( cmdline ) + 1 );
153
+	if ( cmdline_len > BZI_CMDLINE_SIZE )
154
+		cmdline_len = BZI_CMDLINE_SIZE;
155
+	copy_to_user ( exec_ctx->rm_kernel, exec_ctx->rm_cmdline,
156
+		       cmdline, cmdline_len );
157
+	DBGC ( image, "bzImage %p command line \"%s\"\n", image, cmdline );
158
+
159
+	return 0;
160
+}
161
+
70
 /**
162
 /**
71
  * Execute bzImage image
163
  * Execute bzImage image
72
  *
164
  *
74
  * @ret rc		Return status code
166
  * @ret rc		Return status code
75
  */
167
  */
76
 static int bzimage_exec ( struct image *image ) {
168
 static int bzimage_exec ( struct image *image ) {
77
-	union {
78
-		struct bzimage_exec_context bz;
79
-		unsigned long ul;
80
-	} exec_ctx;
169
+	struct bzimage_exec_context exec_ctx;
170
+	struct bzimage_header bzhdr;
171
+	const char *cmdline = ( image->cmdline ? image->cmdline : "" );
172
+	int rc;
81
 
173
 
82
-	/* Retrieve stored execution context */
83
-	exec_ctx.ul = image->priv.ul;
174
+	/* Retrieve kernel header */
175
+	exec_ctx.rm_kernel_seg = image->priv.ul;
176
+	exec_ctx.rm_kernel = real_to_user ( exec_ctx.rm_kernel_seg, 0 );
177
+	copy_from_user ( &bzhdr, exec_ctx.rm_kernel, BZI_HDR_OFFSET,
178
+			 sizeof ( bzhdr ) );
179
+	exec_ctx.rm_cmdline = exec_ctx.rm_heap = 
180
+		( bzhdr.heap_end_ptr + 0x200 );
181
+	exec_ctx.vid_mode = bzhdr.vid_mode;
182
+	exec_ctx.mem_limit = 0;
183
+
184
+	/* Parse command line for bootloader parameters */
185
+	if ( ( rc = bzimage_parse_cmdline ( image, &exec_ctx, cmdline ) ) != 0)
186
+		return rc;
187
+
188
+	/* Store command line */
189
+	if ( ( rc = bzimage_set_cmdline ( image, &exec_ctx, cmdline ) ) != 0 )
190
+		return rc;
191
+
192
+	/* Update and store kernel header */
193
+	bzhdr.vid_mode = exec_ctx.vid_mode;
194
+	copy_to_user ( exec_ctx.rm_kernel, BZI_HDR_OFFSET, &bzhdr,
195
+		       sizeof ( bzhdr ) );
84
 
196
 
85
 	/* Prepare for exiting */
197
 	/* Prepare for exiting */
86
 	shutdown();
198
 	shutdown();
95
 					   "pushw %w2\n\t"
207
 					   "pushw %w2\n\t"
96
 					   "pushw $0\n\t"
208
 					   "pushw $0\n\t"
97
 					   "lret\n\t" )
209
 					   "lret\n\t" )
98
-			       : : "r" ( exec_ctx.bz.kernel_seg ),
99
-			           "r" ( exec_ctx.bz.stack ),
100
-			           "r" ( exec_ctx.bz.kernel_seg + 0x20 ) );
210
+			       : : "r" ( exec_ctx.rm_kernel_seg ),
211
+			           "r" ( exec_ctx.rm_heap ),
212
+			           "r" ( exec_ctx.rm_kernel_seg + 0x20 ) );
101
 
213
 
102
 	/* There is no way for the image to return, since we provide
214
 	/* There is no way for the image to return, since we provide
103
 	 * no return address.
215
 	 * no return address.
168
  *
280
  *
169
  * @v image		bzImage file
281
  * @v image		bzImage file
170
  * @v load_ctx		Load context
282
  * @v load_ctx		Load context
171
- * @v cmdline		Kernel command line
172
  * @ret rc		Return status code
283
  * @ret rc		Return status code
173
  */
284
  */
174
 static int bzimage_load_real ( struct image *image,
285
 static int bzimage_load_real ( struct image *image,
175
-			       struct bzimage_load_context *load_ctx,
176
-			       const char *cmdline ) {
177
-	size_t cmdline_len = ( strlen ( cmdline ) + 1 );
286
+			       struct bzimage_load_context *load_ctx ) {
178
 	int rc;
287
 	int rc;
179
 
288
 
180
 	/* Allow space for the stack and heap */
289
 	/* Allow space for the stack and heap */
181
 	load_ctx->rm_memsz += BZI_STACK_SIZE;
290
 	load_ctx->rm_memsz += BZI_STACK_SIZE;
182
 	load_ctx->rm_heap = load_ctx->rm_memsz;
291
 	load_ctx->rm_heap = load_ctx->rm_memsz;
183
 
292
 
184
-	/* Allow space for the command line, if one exists */
293
+	/* Allow space for the command line */
185
 	load_ctx->rm_cmdline = load_ctx->rm_memsz;
294
 	load_ctx->rm_cmdline = load_ctx->rm_memsz;
186
-	load_ctx->rm_memsz += cmdline_len;
295
+	load_ctx->rm_memsz += BZI_CMDLINE_SIZE;
187
 
296
 
188
 	/* Prepare, verify, and load the real-mode segment */
297
 	/* Prepare, verify, and load the real-mode segment */
189
 	if ( ( rc = prep_segment ( load_ctx->rm_kernel, load_ctx->rm_filesz,
298
 	if ( ( rc = prep_segment ( load_ctx->rm_kernel, load_ctx->rm_filesz,
195
 	memcpy_user ( load_ctx->rm_kernel, 0, image->data, 0,
304
 	memcpy_user ( load_ctx->rm_kernel, 0, image->data, 0,
196
 		      load_ctx->rm_filesz );
305
 		      load_ctx->rm_filesz );
197
 
306
 
198
-	/* Copy command line */
199
-	copy_to_user ( load_ctx->rm_kernel, load_ctx->rm_cmdline,
200
-		       cmdline, cmdline_len );
201
-
202
 	return 0;
307
 	return 0;
203
 }
308
 }
204
 
309
 
226
 	return 0;
331
 	return 0;
227
 }
332
 }
228
 
333
 
229
-
230
 /**
334
 /**
231
  * Update and store bzImage header
335
  * Update and store bzImage header
232
  *
336
  *
269
  * @ret rc		Return status code
373
  * @ret rc		Return status code
270
  */
374
  */
271
 int bzimage_load ( struct image *image ) {
375
 int bzimage_load ( struct image *image ) {
272
-	struct bzimage_header bzhdr;
273
 	struct bzimage_load_context load_ctx;
376
 	struct bzimage_load_context load_ctx;
274
-	union {
275
-		struct bzimage_exec_context bz;
276
-		unsigned long ul;
277
-	} exec_ctx;
278
-	const char *cmdline = ( image->cmdline ? image->cmdline : "" );
377
+	struct bzimage_header bzhdr;
279
 	int rc;
378
 	int rc;
280
 
379
 
281
 	/* Load and verify header */
380
 	/* Load and verify header */
287
 		image->type = &bzimage_image_type;
386
 		image->type = &bzimage_image_type;
288
 
387
 
289
 	/* Load real-mode portion */
388
 	/* Load real-mode portion */
290
-	if ( ( rc = bzimage_load_real ( image, &load_ctx, cmdline ) ) != 0 )
389
+	if ( ( rc = bzimage_load_real ( image, &load_ctx ) ) != 0 )
291
 		return rc;
390
 		return rc;
292
 
391
 
293
 	/* Load non-real-mode portion */
392
 	/* Load non-real-mode portion */
298
 	if ( ( rc = bzimage_write_header ( image, &load_ctx, &bzhdr ) ) != 0 )
397
 	if ( ( rc = bzimage_write_header ( image, &load_ctx, &bzhdr ) ) != 0 )
299
 		return rc;
398
 		return rc;
300
 
399
 
301
-	/* Record execution context in image private data field */
302
-	exec_ctx.bz.kernel_seg = load_ctx.rm_kernel_seg;
303
-	exec_ctx.bz.stack = load_ctx.rm_heap;
304
-	image->priv.ul = exec_ctx.ul;
400
+	/* Record real-mode segment in image private data field */
401
+	image->priv.ul = load_ctx.rm_kernel_seg;
305
 
402
 
306
 	return 0;
403
 	return 0;
307
 }
404
 }

+ 12
- 0
src/arch/i386/include/bzimage.h View File

85
 /** bzImage "kernel can use heap" flag */
85
 /** bzImage "kernel can use heap" flag */
86
 #define BZI_CAN_USE_HEAP 0x80
86
 #define BZI_CAN_USE_HEAP 0x80
87
 
87
 
88
+/** bzImage special video mode "normal" */
89
+#define BZI_VID_MODE_NORMAL 0xffff
90
+
91
+/** bzImage special video mode "ext" */
92
+#define BZI_VID_MODE_EXT 0xfffe
93
+
94
+/** bzImage special video mode "ask" */
95
+#define BZI_VID_MODE_ASK 0xfffd
96
+
88
 
97
 
89
 /** bzImage command-line structure used by older kernels */
98
 /** bzImage command-line structure used by older kernels */
90
 struct bzimage_cmdline {
99
 struct bzimage_cmdline {
104
 /** Amount of stack space to provide */
113
 /** Amount of stack space to provide */
105
 #define BZI_STACK_SIZE 0x1000
114
 #define BZI_STACK_SIZE 0x1000
106
 
115
 
116
+/** Maximum size of command line */
117
+#define BZI_CMDLINE_SIZE 0x100
118
+
107
 #endif /* _BZIMAGE_H */
119
 #endif /* _BZIMAGE_H */

Loading…
Cancel
Save