Browse Source

Populate multiboot information structure before calling OS.

tags/v0.9.3
Michael Brown 18 years ago
parent
commit
f31d91bce5
1 changed files with 39 additions and 17 deletions
  1. 39
    17
      src/arch/i386/image/multiboot.c

+ 39
- 17
src/arch/i386/image/multiboot.c View File

28
 #include <gpxe/uaccess.h>
28
 #include <gpxe/uaccess.h>
29
 #include <gpxe/image.h>
29
 #include <gpxe/image.h>
30
 #include <gpxe/segment.h>
30
 #include <gpxe/segment.h>
31
+#include <gpxe/memmap.h>
31
 #include <gpxe/elf.h>
32
 #include <gpxe/elf.h>
32
 
33
 
33
-/** Boot modules must be page aligned */
34
-#define MB_FLAG_PGALIGN 0x00000001
35
-
36
-/** Memory map must be provided */
37
-#define MB_FLAG_MEMMAP 0x00000002
38
-
39
-/** Video mode information must be provided */
40
-#define MB_FLAG_VIDMODE 0x00000004
41
-
42
-/** Image is a raw multiboot image (not ELF) */
43
-#define MB_FLAG_RAW 0x00010000
44
-
45
 /** Multiboot flags that we support */
34
 /** Multiboot flags that we support */
46
 #define MB_SUPPORTED_FLAGS ( MB_FLAG_PGALIGN | MB_FLAG_MEMMAP | \
35
 #define MB_SUPPORTED_FLAGS ( MB_FLAG_PGALIGN | MB_FLAG_MEMMAP | \
47
 			     MB_FLAG_VIDMODE | MB_FLAG_RAW )
36
 			     MB_FLAG_VIDMODE | MB_FLAG_RAW )
75
  * @ret rc		Return status code
64
  * @ret rc		Return status code
76
  */
65
  */
77
 static int multiboot_execute ( struct image *image ) {
66
 static int multiboot_execute ( struct image *image ) {
67
+	static const char *bootloader_name = "gPXE " VERSION;
78
 	struct multiboot_info mbinfo;
68
 	struct multiboot_info mbinfo;
69
+	struct memory_map memmap;
70
+	struct multiboot_memory_map mbmemmap[ sizeof ( memmap.regions ) /
71
+					      sizeof ( memmap.regions[0] ) ];
72
+	unsigned int i;
79
 
73
 
80
 	/* Populate multiboot information structure */
74
 	/* Populate multiboot information structure */
81
 	memset ( &mbinfo, 0, sizeof ( mbinfo ) );
75
 	memset ( &mbinfo, 0, sizeof ( mbinfo ) );
76
+
77
+	/* Set boot loader name */
78
+	mbinfo.flags |= MBI_FLAG_LOADER;
79
+	mbinfo.boot_loader_name = virt_to_phys ( bootloader_name );
82
 	
80
 	
81
+	/* Get memory map */
82
+	get_memmap ( &memmap );
83
+	memset ( mbmemmap, 0, sizeof ( mbmemmap ) );
84
+	for ( i = 0 ; i < memmap.count ; i++ ) {
85
+		mbmemmap[i].size = sizeof ( mbmemmap[i] );
86
+		mbmemmap[i].base_addr = memmap.regions[i].start;
87
+		mbmemmap[i].length = ( memmap.regions[i].end -
88
+				       memmap.regions[i].start );
89
+		mbmemmap[i].type = MBMEM_RAM;
90
+		mbinfo.mmap_length += sizeof ( mbmemmap[i] );
91
+		if ( memmap.regions[i].start == 0 )
92
+			mbinfo.mem_lower = memmap.regions[i].end;
93
+		if ( memmap.regions[i].start == 0x100000 )
94
+			mbinfo.mem_upper = ( memmap.regions[i].end - 0x100000);
95
+	}
96
+	mbinfo.flags |= ( MBI_FLAG_MEM | MBI_FLAG_MMAP );
97
+	mbinfo.mmap_addr = virt_to_phys ( &mbmemmap[0].base_addr );
98
+
99
+	/* Set command line, if present */
100
+	if ( image->cmdline ) {
101
+		mbinfo.flags |= MBI_FLAG_CMDLINE;
102
+		mbinfo.cmdline = virt_to_phys ( image->cmdline );
103
+	}
83
 
104
 
84
 	/* Jump to OS with flat physical addressing */
105
 	/* Jump to OS with flat physical addressing */
85
-	__asm__ ( PHYS_CODE ( "call *%%edi\n\t" )
86
-		  : : "a" ( MULTIBOOT_BOOTLOADER_MAGIC ),
87
-		      "b" ( virt_to_phys ( &mbinfo ) ),
88
-		      "D" ( image->entry )
89
-		  : "ecx", "edx", "esi", "ebp" );
106
+	__asm__ __volatile__ ( PHYS_CODE ( "xchgw %%bx,%%bx\n\t"
107
+					   "call *%%edi\n\t" )
108
+			       : : "a" ( MULTIBOOT_BOOTLOADER_MAGIC ),
109
+			           "b" ( virt_to_phys ( &mbinfo ) ),
110
+			           "D" ( image->entry )
111
+			       : "ecx", "edx", "esi", "ebp" );
90
 
112
 
91
 	return -ECANCELED;
113
 	return -ECANCELED;
92
 }
114
 }

Loading…
Cancel
Save