⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mboot.c

📁 linux内核
💻 C
📖 第 1 页 / 共 3 页
字号:
#endif}static void init_mmap(struct multiboot_info *mbi)    /* Get a full memory map from the BIOS to pass to the kernel. */{    com32sys_t regs_in, regs_out;    struct AddrRangeDesc *e820;    int e820_slots;    size_t mem_lower, mem_upper, run_addr, mmap_size;    register size_t sp;    /* Default values for mem_lower and mem_upper in case the BIOS won't      * tell us: 640K, and all memory up to the stack. */    asm volatile("movl %%esp, %0" : "=r" (sp));    mem_upper = (sp - MEM_HOLE_END) / 1024;    mem_lower = (MEM_HOLE_START) / 1024;#ifdef DEBUG    printf("Requesting memory map from BIOS:\n");#endif        /* Ask the BIOS for the full memory map of the machine.  We'll     * build it in Multiboot format (i.e. with size fields) in the     * bounce buffer, and then allocate some high memory to keep it in     * until boot time. */    e820 = __com32.cs_bounce;    e820_slots = 0;    regs_out.ebx.l = 0;        while(((void *)(e820 + 1)) < __com32.cs_bounce + __com32.cs_bounce_size)     {        e820->size = sizeof(*e820) - sizeof(e820->size);              /* Ask the BIOS to fill in this descriptor */        regs_in.eax.l = 0xe820;         /* "Get system memory map" */        regs_in.ebx.l = regs_out.ebx.l; /* Continuation value from last call */        regs_in.ecx.l = 20;             /* Size of buffer to write into */        regs_in.edx.l = 0x534d4150;     /* "SMAP" */        regs_in.es = SEG(&e820->BaseAddr);        regs_in.edi.w[0] = OFFS(&e820->BaseAddr);        __intcall(0x15, &regs_in, &regs_out);                if ((regs_out.eflags.l & EFLAGS_CF) != 0 && regs_out.ebx.l != 0)            break;  /* End of map */        if (((regs_out.eflags.l & EFLAGS_CF) != 0 && regs_out.ebx.l == 0)            || (regs_out.eax.l != 0x534d4150))        {                       /* Error */            printf("Error %x reading E820 memory map: %s.\n",                    (int) regs_out.eax.b[0],                   (regs_out.eax.b[0] == 0x80) ? "invalid command" :                   (regs_out.eax.b[0] == 0x86) ? "not supported" :                   "unknown error");            break;        }         /* Success */#ifdef DEBUG        printf("    %#16.16Lx -- %#16.16Lx : ",                e820->BaseAddr, e820->BaseAddr + e820->Length);        switch (e820->Type) {        case 1: printf("Available\n"); break;         case 2: printf("Reserved\n"); break;         case 3: printf("ACPI Reclaim\n"); break;         case 4: printf("ACPI NVS\n"); break;         default: printf("? (Reserved)\n"); break;         }#endif        if (e820->Type == 1) {            if (e820->BaseAddr == 0) {                mem_lower = MIN(MEM_HOLE_START, e820->Length) / 1024;            } else if (e820->BaseAddr == MEM_HOLE_END) {                mem_upper = MIN(0xfff00000, e820->Length) / 1024;            }        }        /* Move to next slot */         e820++;        e820_slots++;                /* Done? */        if (regs_out.ebx.l == 0)             break;    }    /* Record the simple information in the MBI */    mbi->flags |= MB_INFO_MEMORY;    mbi->mem_lower = mem_lower;    mbi->mem_upper = mem_upper;        /* Record the full memory map in the MBI */    if (e820_slots != 0) {        mmap_size = e820_slots * sizeof(*e820);        /* Where will it live at run time? */         run_addr = place_low_section(mmap_size, 1);        if (run_addr == 0) {            printf("Fatal: can't find space for the e820 mmap.\n");            exit(1);        }        /* Where will it live now? */        e820 = (struct AddrRangeDesc *) next_load_addr;        if (next_load_addr + mmap_size > section_addr) {            printf("Fatal: out of memory storing the e820 mmap.\n");            exit(1);        }        next_load_addr += mmap_size;        /* Copy it out of the bounce buffer */        memcpy(e820, __com32.cs_bounce, mmap_size);        /* Remember to copy it again at run time */        add_section(run_addr, (char *) e820, mmap_size);        /* Record it in the MBI */        mbi->flags |= MB_INFO_MEM_MAP;        mbi->mmap_length = mmap_size;        mbi->mmap_addr = run_addr;    }}/* *  Code for loading and parsing files. */static void load_file(char *filename, char **startp, size_t *sizep)     /* Load a file into memory.  Returns where it is and how big via     * startp and sizep */{    gzFile fp;    char *start;    int bsize;        printf("Loading %s.", filename);    start = next_load_addr;    startp[0] = start;    sizep[0] = 0;    /* Open the file */    if ((fp = gzopen(filename, "r")) == NULL) {        printf("\nFatal: cannot open %s\n", filename);        exit(1);    }        while (next_load_addr + LOAD_CHUNK <= section_addr) {        bsize = gzread(fp, next_load_addr, LOAD_CHUNK);        printf("%s",".");        if (bsize < 0) {            printf("\nFatal: read error in %s\n", filename);            gzclose(fp);            exit(1);        }              next_load_addr += bsize;        sizep[0] += bsize;        if (bsize < LOAD_CHUNK) {            printf("%s","\n");            gzclose(fp);                    return;        }    }    /* Running out of memory.  Try and use up the last bit */    if (section_addr > next_load_addr) {        bsize = gzread(fp, next_load_addr, section_addr - next_load_addr);        printf("%s",".");    } else {        bsize = 0;    }        if (bsize < 0) {        gzclose(fp);        printf("\nFatal: read error in %s\n", filename);        exit(1);    }        next_load_addr += bsize;    sizep[0] += bsize;        if (!gzeof(fp)) {        gzclose(fp);        printf("\nFatal: out of memory reading %s\n", filename);        exit(1);    }    printf("%s","\n");    gzclose(fp);    return;}static size_t load_kernel(char *cmdline)     /* Load a multiboot/elf32 kernel and allocate run-time memory for it.     * Returns the kernel's entry address.  */{    unsigned int i;    char *load_addr;                  /* Where the image was loaded */    size_t load_size;                              /* How big it is */    char *seg_addr;                   /* Where a segment was loaded */    size_t seg_size, bss_size;                     /* How big it is */    size_t run_addr, run_size;            /* Where it should be put */    char *p;     Elf32_Ehdr *ehdr;    Elf32_Phdr *phdr;    struct multiboot_header *mbh;    printf("Kernel: %s\n", cmdline);    load_addr = 0;     load_size = 0;    p = strchr(cmdline, ' ');     if (p != NULL) *p = 0;    load_file(cmdline, &load_addr, &load_size);    if (load_size < 12) {        printf("Fatal: %s is too short to be a multiboot kernel.",                cmdline);        exit(1);    }    if (p != NULL) *p = ' ';    /* Look for a multiboot header in the first 8k of the file */    for (i = 0; i <= MIN(load_size - 12, MULTIBOOT_SEARCH - 12); i += 4)    {        mbh = (struct multiboot_header *)(load_addr + i);        if (mbh->magic != MULTIBOOT_MAGIC             || ((mbh->magic+mbh->flags+mbh->checksum) & 0xffffffff))        {            /* Not a multiboot header */            continue;        }        if (mbh->flags & (MULTIBOOT_UNSUPPORTED | MULTIBOOT_VIDEO_MODE)) {            /* Requires options we don't support */            printf("Fatal: Kernel requires multiboot options "                   "that I don't support: %#x.\n",                    mbh->flags & (MULTIBOOT_UNSUPPORTED|MULTIBOOT_VIDEO_MODE));            exit(1);        }        /* This kernel will do: figure out where all the pieces will live */        if (mbh->flags & MULTIBOOT_AOUT_KLUDGE) {            /* Use the offsets in the multiboot header */#ifdef DEBUG            printf("Using multiboot header.\n");#endif            /* Where is the code in the loaded file? */            seg_addr = ((char *)mbh) - (mbh->header_addr - mbh->load_addr);            /* How much code is there? */            run_addr = mbh->load_addr;            if (mbh->load_end_addr != 0)                 seg_size = mbh->load_end_addr - mbh->load_addr;            else                 seg_size = load_size - (seg_addr - load_addr);            /* How much memory will it take up? */             if (mbh->bss_end_addr != 0)                run_size = mbh->bss_end_addr - mbh->load_addr;            else                run_size = seg_size;                        if (seg_size > run_size) {                printf("Fatal: can't put %i bytes of kernel into %i bytes "                        "of memory.\n", seg_size, run_size);                exit(1);            }            if (seg_addr + seg_size > load_addr + load_size) {                printf("Fatal: multiboot load segment runs off the "                        "end of the file.\n");                exit(1);            }            /* Does it fit where it wants to be? */            place_kernel_section(run_addr, run_size);                        /* Put it on the relocation list */            if (seg_size < run_size) {                /* Set up the kernel BSS too */                if (seg_size > 0)                     add_section(run_addr, seg_addr, seg_size);                bss_size = run_size - seg_size;                add_section(run_addr + seg_size, NULL, bss_size);            } else {                /* No BSS */                add_section(run_addr, seg_addr, run_size);            }                        /* Done. */            return mbh->entry_addr;                    } else {                      /* Now look for an ELF32 header */                ehdr = (Elf32_Ehdr *)load_addr;            if (*(unsigned long *)ehdr != 0x464c457f                 || ehdr->e_ident[EI_DATA] != ELFDATA2LSB                || ehdr->e_ident[EI_CLASS] != ELFCLASS32                || ehdr->e_machine != EM_386)            {                printf("Fatal: kernel has neither ELF32/x86 nor multiboot load"                       " headers.\n");                exit(1);            }            if (ehdr->e_phoff + ehdr->e_phnum*sizeof (*phdr) > load_size) {                printf("Fatal: malformed ELF header overruns EOF.\n");                exit(1);            }            if (ehdr->e_phnum <= 0) {                printf("Fatal: ELF kernel has no program headers.\n");                exit(1);            }#ifdef DEBUG            printf("Using ELF header.\n");#endif            if (ehdr->e_type != ET_EXEC 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -