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;