|
|
1.1 ! root 1: /* Support for Multiboot */ ! 2: ! 3: #include "config.h" ! 4: #include "asm/io.h" ! 5: #include "libopenbios/sys_info.h" ! 6: #include "multiboot.h" ! 7: ! 8: #ifdef CONFIG_DEBUG_BOOT ! 9: #define debug printk ! 10: #else ! 11: #define debug(x...) ! 12: #endif ! 13: ! 14: struct mbheader { ! 15: unsigned int magic, flags, checksum; ! 16: }; ! 17: ! 18: static const struct mbheader multiboot_header ! 19: __attribute__((section (".hdr"))) = ! 20: { ! 21: MULTIBOOT_HEADER_MAGIC, ! 22: MULTIBOOT_HEADER_FLAGS, ! 23: -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) ! 24: }; ! 25: ! 26: /* Multiboot information structure, provided by loader to us */ ! 27: ! 28: struct multiboot_mmap { ! 29: unsigned entry_size; ! 30: unsigned base_lo, base_hi; ! 31: unsigned size_lo, size_hi; ! 32: unsigned type; ! 33: }; ! 34: ! 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 ! 42: ! 43: void collect_multiboot_info(struct sys_info *info); ! 44: void collect_multiboot_info(struct sys_info *info) ! 45: { ! 46: struct multiboot_info *mbinfo; ! 47: struct multiboot_mmap *mbmem; ! 48: unsigned mbcount, mbaddr; ! 49: int i; ! 50: struct memrange *mmap; ! 51: int mmap_count; ! 52: module_t *mod; ! 53: ! 54: if (info->boot_type != 0x2BADB002) ! 55: return; ! 56: ! 57: debug("Using Multiboot information at %#lx\n", info->boot_data); ! 58: ! 59: mbinfo = phys_to_virt(info->boot_data); ! 60: ! 61: if (mbinfo->mods_count != 1) { ! 62: printk("multiboot: no dictionary\n"); ! 63: return; ! 64: } ! 65: ! 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); ! 71: ! 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)); ! 77: mmap_count = 0; ! 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", ! 82: mbmem->base_hi, ! 83: mbmem->base_lo, ! 84: mbmem->size_hi, ! 85: mbmem->size_lo, ! 86: mbmem->type); ! 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); ! 92: mmap_count++; ! 93: } ! 94: mbaddr += mbmem->entry_size + 4; ! 95: if (mbaddr >= mbinfo->mmap_addr + mbinfo->mmap_length) ! 96: break; ! 97: } ! 98: /* simple sanity check - there should be at least 2 RAM segments ! 99: * (base 640k and extended) */ ! 100: if (mmap_count >= 2) ! 101: goto got_it; ! 102: ! 103: printk("Multiboot mmap is broken\n"); ! 104: free(mmap); ! 105: /* fall back to mem_lower/mem_upper */ ! 106: } ! 107: ! 108: if (mbinfo->flags & MULTIBOOT_MEM_VALID) { ! 109: /* use mem_lower and mem_upper */ ! 110: mmap_count = 2; ! 111: mmap = malloc(2 * sizeof(*mmap)); ! 112: mmap[0].base = 0; ! 113: mmap[0].size = mbinfo->mem_lower << 10; ! 114: mmap[1].base = 1 << 20; /* 1MB */ ! 115: mmap[1].size = mbinfo->mem_upper << 10; ! 116: goto got_it; ! 117: } ! 118: ! 119: printk("Can't get memory information from Multiboot\n"); ! 120: return; ! 121: ! 122: got_it: ! 123: info->memrange = mmap; ! 124: info->n_memranges = mmap_count; ! 125: ! 126: return; ! 127: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.