Annotation of qemu/roms/openbios/arch/amd64/multiboot.c, revision 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: #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: }

unix.superglobalmegacorp.com

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