|
|
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: #define printf printk ! 9: #ifdef CONFIG_DEBUG_BOOT ! 10: #define debug printk ! 11: #else ! 12: #define debug(x...) ! 13: #endif ! 14: ! 15: struct mbheader { ! 16: unsigned int magic, flags, checksum; ! 17: }; ! 18: 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: printf("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: ! 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)); ! 75: mmap_count = 0; ! 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", ! 80: mbmem->base_hi, ! 81: mbmem->base_lo, ! 82: mbmem->size_hi, ! 83: mbmem->size_lo, ! 84: mbmem->type); ! 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); ! 90: mmap_count++; ! 91: } ! 92: mbaddr += mbmem->entry_size + 4; ! 93: if (mbaddr >= mbinfo->mmap_addr + mbinfo->mmap_length) ! 94: break; ! 95: } ! 96: /* simple sanity check - there should be at least 2 RAM segments ! 97: * (base 640k and extended) */ ! 98: if (mmap_count >= 2) ! 99: goto got_it; ! 100: ! 101: printf("Multiboot mmap is broken\n"); ! 102: free(mmap); ! 103: /* fall back to mem_lower/mem_upper */ ! 104: } ! 105: ! 106: if (mbinfo->flags & MULTIBOOT_MEM_VALID) { ! 107: /* use mem_lower and mem_upper */ ! 108: mmap_count = 2; ! 109: mmap = malloc(2 * sizeof(*mmap)); ! 110: mmap[0].base = 0; ! 111: mmap[0].size = mbinfo->mem_lower << 10; ! 112: mmap[1].base = 1 << 20; /* 1MB */ ! 113: mmap[1].size = mbinfo->mem_upper << 10; ! 114: goto got_it; ! 115: } ! 116: ! 117: printf("Can't get memory information from Multiboot\n"); ! 118: return; ! 119: ! 120: got_it: ! 121: info->memrange = mmap; ! 122: info->n_memranges = mmap_count; ! 123: ! 124: return; ! 125: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.