Kaynağa Gözat

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 yıl önce
ebeveyn
işleme
8a490146bf
2 değiştirilmiş dosya ile 144 ekleme ve 35 silme
  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 Dosyayı Görüntüle

@@ -23,6 +23,9 @@
23 23
  *
24 24
  */
25 25
 
26
+#include <stdint.h>
27
+#include <stdlib.h>
28
+#include <string.h>
26 29
 #include <errno.h>
27 30
 #include <assert.h>
28 31
 #include <realmode.h>
@@ -61,12 +64,101 @@ struct bzimage_load_context {
61 64
  * bzImage execution context
62 65
  */
63 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 163
  * Execute bzImage image
72 164
  *
@@ -74,13 +166,33 @@ struct bzimage_exec_context {
74 166
  * @ret rc		Return status code
75 167
  */
76 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 197
 	/* Prepare for exiting */
86 198
 	shutdown();
@@ -95,9 +207,9 @@ static int bzimage_exec ( struct image *image ) {
95 207
 					   "pushw %w2\n\t"
96 208
 					   "pushw $0\n\t"
97 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 214
 	/* There is no way for the image to return, since we provide
103 215
 	 * no return address.
@@ -168,22 +280,19 @@ static int bzimage_load_header ( struct image *image,
168 280
  *
169 281
  * @v image		bzImage file
170 282
  * @v load_ctx		Load context
171
- * @v cmdline		Kernel command line
172 283
  * @ret rc		Return status code
173 284
  */
174 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 287
 	int rc;
179 288
 
180 289
 	/* Allow space for the stack and heap */
181 290
 	load_ctx->rm_memsz += BZI_STACK_SIZE;
182 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 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 297
 	/* Prepare, verify, and load the real-mode segment */
189 298
 	if ( ( rc = prep_segment ( load_ctx->rm_kernel, load_ctx->rm_filesz,
@@ -195,10 +304,6 @@ static int bzimage_load_real ( struct image *image,
195 304
 	memcpy_user ( load_ctx->rm_kernel, 0, image->data, 0,
196 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 307
 	return 0;
203 308
 }
204 309
 
@@ -226,7 +331,6 @@ static int bzimage_load_non_real ( struct image *image,
226 331
 	return 0;
227 332
 }
228 333
 
229
-
230 334
 /**
231 335
  * Update and store bzImage header
232 336
  *
@@ -269,13 +373,8 @@ static int bzimage_write_header ( struct image *image __unused,
269 373
  * @ret rc		Return status code
270 374
  */
271 375
 int bzimage_load ( struct image *image ) {
272
-	struct bzimage_header bzhdr;
273 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 378
 	int rc;
280 379
 
281 380
 	/* Load and verify header */
@@ -287,7 +386,7 @@ int bzimage_load ( struct image *image ) {
287 386
 		image->type = &bzimage_image_type;
288 387
 
289 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 390
 		return rc;
292 391
 
293 392
 	/* Load non-real-mode portion */
@@ -298,10 +397,8 @@ int bzimage_load ( struct image *image ) {
298 397
 	if ( ( rc = bzimage_write_header ( image, &load_ctx, &bzhdr ) ) != 0 )
299 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 403
 	return 0;
307 404
 }

+ 12
- 0
src/arch/i386/include/bzimage.h Dosyayı Görüntüle

@@ -85,6 +85,15 @@ struct bzimage_header {
85 85
 /** bzImage "kernel can use heap" flag */
86 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 98
 /** bzImage command-line structure used by older kernels */
90 99
 struct bzimage_cmdline {
@@ -104,4 +113,7 @@ struct bzimage_cmdline {
104 113
 /** Amount of stack space to provide */
105 114
 #define BZI_STACK_SIZE 0x1000
106 115
 
116
+/** Maximum size of command line */
117
+#define BZI_CMDLINE_SIZE 0x100
118
+
107 119
 #endif /* _BZIMAGE_H */

Loading…
İptal
Kaydet