1 /* Support for Multiboot */
5 #include "libopenbios/sys_info.h"
8 #ifdef CONFIG_DEBUG_BOOT
15 unsigned int magic
, flags
, checksum
;
18 static 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 printk("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
;
69 debug("multiboot: dictionary at %p-%p\n",
70 info
->dict_start
, info
->dict_end
);
72 if (mbinfo
->flags
& MULTIBOOT_MMAP_VALID
) {
73 /* convert mmap records */
74 mbmem
= phys_to_virt(mbinfo
->mmap_addr
);
75 mbcount
= mbinfo
->mmap_length
/ (mbmem
->entry_size
+ 4);
76 mmap
= malloc(mbcount
* sizeof(struct memrange
));
78 mbaddr
= mbinfo
->mmap_addr
;
79 for (i
= 0; i
< mbcount
; i
++) {
80 mbmem
= phys_to_virt(mbaddr
);
81 debug("%08x%08x %08x%08x (%d)\n",
87 if (mbmem
->type
== 1) { /* Only normal RAM */
88 mmap
[mmap_count
].base
= mbmem
->base_lo
89 + (((unsigned long long) mbmem
->base_hi
) << 32);
90 mmap
[mmap_count
].size
= mbmem
->size_lo
91 + (((unsigned long long) mbmem
->size_hi
) << 32);
94 mbaddr
+= mbmem
->entry_size
+ 4;
95 if (mbaddr
>= mbinfo
->mmap_addr
+ mbinfo
->mmap_length
)
98 /* simple sanity check - there should be at least 2 RAM segments
99 * (base 640k and extended) */
103 printk("Multiboot mmap is broken\n");
105 /* fall back to mem_lower/mem_upper */
108 if (mbinfo
->flags
& MULTIBOOT_MEM_VALID
) {
109 /* use mem_lower and mem_upper */
111 mmap
= malloc(2 * sizeof(*mmap
));
113 mmap
[0].size
= mbinfo
->mem_lower
<< 10;
114 mmap
[1].base
= 1 << 20; /* 1MB */
115 mmap
[1].size
= mbinfo
->mem_upper
<< 10;
119 printk("Can't get memory information from Multiboot\n");
123 info
->memrange
= mmap
;
124 info
->n_memranges
= mmap_count
;