소스 검색

Populate multiboot information structure before calling OS.

tags/v0.9.3
Michael Brown 18 년 전
부모
커밋
f31d91bce5
1개의 변경된 파일39개의 추가작업 그리고 17개의 파일을 삭제
  1. 39
    17
      src/arch/i386/image/multiboot.c

+ 39
- 17
src/arch/i386/image/multiboot.c 파일 보기

@@ -28,20 +28,9 @@
28 28
 #include <gpxe/uaccess.h>
29 29
 #include <gpxe/image.h>
30 30
 #include <gpxe/segment.h>
31
+#include <gpxe/memmap.h>
31 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 34
 /** Multiboot flags that we support */
46 35
 #define MB_SUPPORTED_FLAGS ( MB_FLAG_PGALIGN | MB_FLAG_MEMMAP | \
47 36
 			     MB_FLAG_VIDMODE | MB_FLAG_RAW )
@@ -75,18 +64,51 @@ struct multiboot_header_info {
75 64
  * @ret rc		Return status code
76 65
  */
77 66
 static int multiboot_execute ( struct image *image ) {
67
+	static const char *bootloader_name = "gPXE " VERSION;
78 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 74
 	/* Populate multiboot information structure */
81 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 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 113
 	return -ECANCELED;
92 114
 }

Loading…
취소
저장