|
@@ -32,6 +32,7 @@
|
32
|
32
|
#include <gpxe/segment.h>
|
33
|
33
|
#include <gpxe/memmap.h>
|
34
|
34
|
#include <gpxe/elf.h>
|
|
35
|
+#include <gpxe/shutdown.h>
|
35
|
36
|
|
36
|
37
|
struct image_type multiboot_image_type __image_type ( PROBE_MULTIBOOT );
|
37
|
38
|
|
|
@@ -76,11 +77,13 @@ struct multiboot_header_info {
|
76
|
77
|
/**
|
77
|
78
|
* Build multiboot memory map
|
78
|
79
|
*
|
|
80
|
+ * @v image Multiboot image
|
79
|
81
|
* @v mbinfo Multiboot information structure
|
80
|
82
|
* @v mbmemmap Multiboot memory map
|
81
|
83
|
* @v limit Maxmimum number of memory map entries
|
82
|
84
|
*/
|
83
|
|
-static void multiboot_build_memmap ( struct multiboot_info *mbinfo,
|
|
85
|
+static void multiboot_build_memmap ( struct image *image,
|
|
86
|
+ struct multiboot_info *mbinfo,
|
84
|
87
|
struct multiboot_memory_map *mbmemmap,
|
85
|
88
|
unsigned int limit ) {
|
86
|
89
|
struct memory_map memmap;
|
|
@@ -93,8 +96,8 @@ static void multiboot_build_memmap ( struct multiboot_info *mbinfo,
|
93
|
96
|
memset ( mbmemmap, 0, sizeof ( *mbmemmap ) );
|
94
|
97
|
for ( i = 0 ; i < memmap.count ; i++ ) {
|
95
|
98
|
if ( i >= limit ) {
|
96
|
|
- DBG ( "Multiboot limit of %d memmap entries reached\n",
|
97
|
|
- limit );
|
|
99
|
+ DBGC ( image, "MULTIBOOT %p limit of %d memmap "
|
|
100
|
+ "entries reached\n", image, limit );
|
98
|
101
|
break;
|
99
|
102
|
}
|
100
|
103
|
mbmemmap[i].size = ( sizeof ( mbmemmap[i] ) -
|
|
@@ -135,8 +138,8 @@ multiboot_build_module_list ( struct image *image,
|
135
|
138
|
for_each_image ( module_image ) {
|
136
|
139
|
|
137
|
140
|
if ( count >= limit ) {
|
138
|
|
- DBG ( "Multiboot limit of %d modules reached\n",
|
139
|
|
- limit );
|
|
141
|
+ DBGC ( image, "MULTIBOOT %p limit of %d modules "
|
|
142
|
+ "reached\n", image, limit );
|
140
|
143
|
break;
|
141
|
144
|
}
|
142
|
145
|
|
|
@@ -176,8 +179,9 @@ multiboot_build_module_list ( struct image *image,
|
176
|
179
|
/* Dump module configuration */
|
177
|
180
|
if ( modules ) {
|
178
|
181
|
for ( i = 0 ; i < count ; i++ ) {
|
179
|
|
- DBG ( "Multiboot module %d is [%lx,%lx)\n", i,
|
180
|
|
- modules[i].mod_start, modules[i].mod_end );
|
|
182
|
+ DBGC ( image, "MULTIBOOT %p module %d is [%lx,%lx)\n",
|
|
183
|
+ image, i, modules[i].mod_start,
|
|
184
|
+ modules[i].mod_end );
|
181
|
185
|
}
|
182
|
186
|
}
|
183
|
187
|
|
|
@@ -219,7 +223,7 @@ static int multiboot_exec ( struct image *image ) {
|
219
|
223
|
memset ( &mbinfo, 0, sizeof ( mbinfo ) );
|
220
|
224
|
mbinfo.flags = ( MBI_FLAG_LOADER | MBI_FLAG_MEM | MBI_FLAG_MMAP |
|
221
|
225
|
MBI_FLAG_CMDLINE | MBI_FLAG_MODS );
|
222
|
|
- multiboot_build_memmap ( &mbinfo, mbmemmap,
|
|
226
|
+ multiboot_build_memmap ( image, &mbinfo, mbmemmap,
|
223
|
227
|
( sizeof(mbmemmap) / sizeof(mbmemmap[0]) ) );
|
224
|
228
|
mbinfo.cmdline = virt_to_phys ( image->cmdline );
|
225
|
229
|
mbinfo.mods_count = multiboot_build_module_list ( image, mbmodules,
|
|
@@ -227,7 +231,12 @@ static int multiboot_exec ( struct image *image ) {
|
227
|
231
|
mbinfo.mods_addr = virt_to_phys ( mbmodules );
|
228
|
232
|
mbinfo.mmap_addr = virt_to_phys ( mbmemmap );
|
229
|
233
|
mbinfo.boot_loader_name = virt_to_phys ( mb_bootloader_name );
|
230
|
|
-
|
|
234
|
+
|
|
235
|
+ /* Multiboot images may not return and have no callback
|
|
236
|
+ * interface, so shut everything down prior to booting the OS.
|
|
237
|
+ */
|
|
238
|
+ shutdown();
|
|
239
|
+
|
231
|
240
|
/* Jump to OS with flat physical addressing */
|
232
|
241
|
__asm__ __volatile__ ( PHYS_CODE ( "call *%%edi\n\t" )
|
233
|
242
|
: : "a" ( MULTIBOOT_BOOTLOADER_MAGIC ),
|
|
@@ -235,7 +244,12 @@ static int multiboot_exec ( struct image *image ) {
|
235
|
244
|
"D" ( image->entry )
|
236
|
245
|
: "ecx", "edx", "esi", "ebp", "memory" );
|
237
|
246
|
|
238
|
|
- return -ECANCELED;
|
|
247
|
+ DBGC ( image, "MULTIBOOT %p returned\n", image );
|
|
248
|
+
|
|
249
|
+ /* It isn't safe to continue after calling shutdown() */
|
|
250
|
+ while ( 1 ) {}
|
|
251
|
+
|
|
252
|
+ return -ECANCELED; /* -EIMPOSSIBLE, anyone? */
|
239
|
253
|
}
|
240
|
254
|
|
241
|
255
|
/**
|
|
@@ -306,8 +320,8 @@ static int multiboot_load_raw ( struct image *image,
|
306
|
320
|
memsz = ( hdr->mb.bss_end_addr - hdr->mb.load_addr );
|
307
|
321
|
buffer = phys_to_user ( hdr->mb.load_addr );
|
308
|
322
|
if ( ( rc = prep_segment ( buffer, filesz, memsz ) ) != 0 ) {
|
309
|
|
- DBG ( "Multiboot could not prepare segment: %s\n",
|
310
|
|
- strerror ( rc ) );
|
|
323
|
+ DBGC ( image, "MULTIBOOT %p could not prepare segment: %s\n",
|
|
324
|
+ image, strerror ( rc ) );
|
311
|
325
|
return rc;
|
312
|
326
|
}
|
313
|
327
|
|
|
@@ -331,8 +345,8 @@ static int multiboot_load_elf ( struct image *image ) {
|
331
|
345
|
|
332
|
346
|
/* Load ELF image*/
|
333
|
347
|
if ( ( rc = elf_load ( image ) ) != 0 ) {
|
334
|
|
- DBG ( "Multiboot ELF image failed to load: %s\n",
|
335
|
|
- strerror ( rc ) );
|
|
348
|
+ DBGC ( image, "MULTIBOOT %p ELF image failed to load: %s\n",
|
|
349
|
+ image, strerror ( rc ) );
|
336
|
350
|
return rc;
|
337
|
351
|
}
|
338
|
352
|
|
|
@@ -351,10 +365,12 @@ int multiboot_load ( struct image *image ) {
|
351
|
365
|
|
352
|
366
|
/* Locate multiboot header, if present */
|
353
|
367
|
if ( ( rc = multiboot_find_header ( image, &hdr ) ) != 0 ) {
|
354
|
|
- DBG ( "No multiboot header\n" );
|
|
368
|
+ DBGC ( image, "MULTIBOOT %p has no multiboot header\n",
|
|
369
|
+ image );
|
355
|
370
|
return rc;
|
356
|
371
|
}
|
357
|
|
- DBG ( "Found multiboot header with flags %08lx\n", hdr.mb.flags );
|
|
372
|
+ DBGC ( image, "MULTIBOOT %p found header with flags %08lx\n",
|
|
373
|
+ image, hdr.mb.flags );
|
358
|
374
|
|
359
|
375
|
/* This is a multiboot image, valid or otherwise */
|
360
|
376
|
if ( ! image->type )
|
|
@@ -362,8 +378,8 @@ int multiboot_load ( struct image *image ) {
|
362
|
378
|
|
363
|
379
|
/* Abort if we detect flags that we cannot support */
|
364
|
380
|
if ( hdr.mb.flags & MB_UNSUPPORTED_FLAGS ) {
|
365
|
|
- DBG ( "Multiboot flags %08lx not supported\n",
|
366
|
|
- ( hdr.mb.flags & MB_UNSUPPORTED_FLAGS ) );
|
|
381
|
+ DBGC ( image, "MULTIBOOT %p flags %08lx not supported\n",
|
|
382
|
+ image, ( hdr.mb.flags & MB_UNSUPPORTED_FLAGS ) );
|
367
|
383
|
return -ENOTSUP;
|
368
|
384
|
}
|
369
|
385
|
|