1 /* Support for Multiboot */
5 #include "libopenbios/sys_info.h"
9 #ifdef CONFIG_DEBUG_BOOT
16 unsigned int magic
, flags
, checksum
;
18 const struct mbheader multiboot_header
19 __attribute__((section (".hdr"))) =
21 MULTIBOOT_HEADER_MAGIC
,
22 MULTIBOOT_HEADER_FLAGS
,
23 -(MULTIBOOT_HEADER_MAGIC
+ MULTIBOOT_HEADER_FLAGS
)
26 /* Multiboot information structure, provided by loader to us */
28 struct multiboot_mmap
{
30 unsigned base_lo
, base_hi
;
31 unsigned size_lo
, size_hi
;
35 #define MULTIBOOT_MEM_VALID 0x01
36 #define MULTIBOOT_BOOT_DEV_VALID 0x02
37 #define MULTIBOOT_CMDLINE_VALID 0x04
38 #define MULTIBOOT_MODS_VALID 0x08
39 #define MULTIBOOT_AOUT_SYMS_VALID 0x10
40 #define MULTIBOOT_ELF_SYMS_VALID 0x20
41 #define MULTIBOOT_MMAP_VALID 0x40
43 void collect_multiboot_info(struct sys_info
*info
);
44 void collect_multiboot_info(struct sys_info
*info
)
46 struct multiboot_info
*mbinfo
;
47 struct multiboot_mmap
*mbmem
;
48 unsigned mbcount
, mbaddr
;
50 struct memrange
*mmap
;
54 if (info
->boot_type
!= 0x2BADB002)
57 debug("Using Multiboot information at %#lx\n", info
->boot_data
);
59 mbinfo
= phys_to_virt(info
->boot_data
);
61 if (mbinfo
->mods_count
!= 1) {
62 printf("Multiboot: no dictionary\n");
66 mod
= (module_t
*) mbinfo
->mods_addr
;
67 info
->dict_start
=(unsigned long *)mod
->mod_start
;
68 info
->dict_end
=(unsigned long *)mod
->mod_end
;
70 if (mbinfo
->flags
& MULTIBOOT_MMAP_VALID
) {
71 /* convert mmap records */
72 mbmem
= phys_to_virt(mbinfo
->mmap_addr
);
73 mbcount
= mbinfo
->mmap_length
/ (mbmem
->entry_size
+ 4);
74 mmap
= malloc(mbcount
* sizeof(struct memrange
));
76 mbaddr
= mbinfo
->mmap_addr
;
77 for (i
= 0; i
< mbcount
; i
++) {
78 mbmem
= phys_to_virt(mbaddr
);
79 debug("%08x%08x %08x%08x (%d)\n",
85 if (mbmem
->type
== 1) { /* Only normal RAM */
86 mmap
[mmap_count
].base
= mbmem
->base_lo
87 + (((unsigned long long) mbmem
->base_hi
) << 32);
88 mmap
[mmap_count
].size
= mbmem
->size_lo
89 + (((unsigned long long) mbmem
->size_hi
) << 32);
92 mbaddr
+= mbmem
->entry_size
+ 4;
93 if (mbaddr
>= mbinfo
->mmap_addr
+ mbinfo
->mmap_length
)
96 /* simple sanity check - there should be at least 2 RAM segments
97 * (base 640k and extended) */
101 printf("Multiboot mmap is broken\n");
103 /* fall back to mem_lower/mem_upper */
106 if (mbinfo
->flags
& MULTIBOOT_MEM_VALID
) {
107 /* use mem_lower and mem_upper */
109 mmap
= malloc(2 * sizeof(*mmap
));
111 mmap
[0].size
= mbinfo
->mem_lower
<< 10;
112 mmap
[1].base
= 1 << 20; /* 1MB */
113 mmap
[1].size
= mbinfo
->mem_upper
<< 10;
117 printf("Can't get memory information from Multiboot\n");
121 info
->memrange
= mmap
;
122 info
->n_memranges
= mmap_count
;