Annotation of qemu/roms/openbios/arch/x86/multiboot.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.