Pārlūkot izejas kodu

Can start a Linux kernel directly (albeit with no initrd support)

tags/v0.9.3
Michael Brown 17 gadus atpakaļ
vecāks
revīzija
97a3037f76
1 mainītis faili ar 29 papildinājumiem un 8 dzēšanām
  1. 29
    8
      src/arch/i386/image/bzimage.c

+ 29
- 8
src/arch/i386/image/bzimage.c Parādīt failu

@@ -35,6 +35,20 @@
35 35
 
36 36
 struct image_type bzimage_image_type __image_type ( PROBE_NORMAL );
37 37
 
38
+/**
39
+ * bzImage execution context
40
+ */
41
+union bzimage_exec_context {
42
+	/** Real-mode parameters */
43
+	struct {
44
+		/** Kernel real-mode data segment */
45
+		uint16_t kernel_seg;
46
+		/** Kernel real-mode stack pointer */
47
+		uint16_t stack;
48
+	} rm;
49
+	unsigned long ul;
50
+};
51
+
38 52
 /**
39 53
  * Execute bzImage image
40 54
  *
@@ -42,7 +56,10 @@ struct image_type bzimage_image_type __image_type ( PROBE_NORMAL );
42 56
  * @ret rc		Return status code
43 57
  */
44 58
 static int bzimage_exec ( struct image *image ) {
45
-	unsigned long rm_kernel_seg = image->priv.ul;
59
+	union bzimage_exec_context context;
60
+
61
+	/* Retrieve stored execution context */
62
+	context.ul = image->priv.ul;
46 63
 
47 64
 	/* Prepare for exiting */
48 65
 	shutdown();
@@ -57,13 +74,14 @@ static int bzimage_exec ( struct image *image ) {
57 74
 					   "pushw %w2\n\t"
58 75
 					   "pushw $0\n\t"
59 76
 					   "lret\n\t" )
60
-			       : : "r" ( rm_kernel_seg ),
61
-			           "i" ( BZI_STACK_SIZE ),
62
-			           "r" ( rm_kernel_seg + 0x20 ) );
77
+			       : : "r" ( context.rm.kernel_seg ),
78
+			           "r" ( context.rm.stack ),
79
+			           "r" ( context.rm.kernel_seg + 0x20 ) );
63 80
 
64 81
 	/* There is no way for the image to return, since we provide
65 82
 	 * no return address.
66 83
 	 */
84
+	assert ( 0 );
67 85
 
68 86
 	return -ECANCELED; /* -EIMPOSSIBLE */
69 87
 }
@@ -76,7 +94,8 @@ static int bzimage_exec ( struct image *image ) {
76 94
  */
77 95
 int bzimage_load ( struct image *image ) {
78 96
 	struct bzimage_header bzhdr;
79
-	unsigned int rm_kernel_seg = 0x7c0; /* place RM kernel at 07c0:0000 */
97
+	union bzimage_exec_context context;
98
+	unsigned int rm_kernel_seg = 0x1000; /* place RM kernel at 1000:0000 */
80 99
 	userptr_t rm_kernel = real_to_user ( rm_kernel_seg, 0 );
81 100
 	userptr_t pm_kernel;
82 101
 	size_t rm_filesz;
@@ -115,7 +134,7 @@ int bzimage_load ( struct image *image ) {
115 134
 	DBGC ( image, "bzImage %p version %04x\n", image, bzhdr.version );
116 135
 
117 136
 	/* Check size of base memory portions */
118
-	rm_filesz = ( ( bzhdr.setup_sects ? bzhdr.setup_sects : 4 ) << 9 );
137
+	rm_filesz = ( ( bzhdr.setup_sects ? bzhdr.setup_sects : 4 ) + 1 ) << 9;
119 138
 	if ( rm_filesz > image->len ) {
120 139
 		DBGC ( image, "bzImage %p too short for %zd byte of setup\n",
121 140
 		       image, rm_filesz );
@@ -177,8 +196,10 @@ int bzimage_load ( struct image *image ) {
177 196
 	}
178 197
 	copy_to_user ( rm_kernel, BZI_HDR_OFFSET, &bzhdr, sizeof ( bzhdr ) );
179 198
 
180
-	/* Record segment address in image private data field */
181
-	image->priv.ul = rm_kernel_seg;
199
+	/* Record execution context in image private data field */
200
+	context.rm.kernel_seg = rm_kernel_seg;
201
+	context.rm.stack = rm_heap_end;
202
+	image->priv.ul = context.ul;
182 203
 
183 204
 	return 0;
184 205
 }

Notiek ielāde…
Atcelt
Saglabāt