diff options
Diffstat (limited to 'i386/i386at/model_dep.c')
-rw-r--r-- | i386/i386at/model_dep.c | 65 |
1 files changed, 62 insertions, 3 deletions
diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c index 8e98bd9e..87d6cefa 100644 --- a/i386/i386at/model_dep.c +++ b/i386/i386at/model_dep.c @@ -66,6 +66,7 @@ #include <i386/model_dep.h> #include <i386at/autoconf.h> #include <i386at/biosmem.h> +#include <i386at/elf.h> #include <i386at/idt.h> #include <i386at/int_init.h> #include <i386at/kd.h> @@ -158,9 +159,7 @@ void machine_init(void) * This is particularly important for the Linux drivers which * require available DMA memory. */ -#ifndef MACH_HYP - biosmem_free_usable((struct multiboot_raw_info *) &boot_info); -#endif /* MACH_HYP */ + biosmem_free_usable(); /* * Set up to use floating point. @@ -274,6 +273,65 @@ void db_reset_cpu(void) halt_all_cpus(1); } +#ifndef MACH_HYP + +static void +register_boot_data(const struct multiboot_raw_info *mbi) +{ + struct multiboot_raw_module *mod; + struct elf_shdr *shdr; + unsigned long tmp; + unsigned int i; + + extern char _start[], _end[]; + + /* XXX For now, register all boot data as permanent */ + + biosmem_register_boot_data(_kvtophys(&_start), _kvtophys(&_end), FALSE); + + if ((mbi->flags & MULTIBOOT_LOADER_CMDLINE) && (mbi->cmdline != 0)) { + biosmem_register_boot_data(mbi->cmdline, + mbi->cmdline + strlen((void *)mbi->cmdline) + 1, FALSE); + } + + if (mbi->flags & MULTIBOOT_LOADER_MODULES) { + i = mbi->mods_count * sizeof(struct multiboot_raw_module); + biosmem_register_boot_data(mbi->mods_addr, mbi->mods_addr + i, FALSE); + + tmp = phystokv(mbi->mods_addr); + + for (i = 0; i < mbi->mods_count; i++) { + mod = (struct multiboot_raw_module *)tmp + i; + biosmem_register_boot_data(mod->mod_start, mod->mod_end, FALSE); + + if (mod->string != 0) { + biosmem_register_boot_data(mod->string, + mod->string + strlen((void *)mod->string) + 1, + FALSE); + } + } + } + + if (mbi->flags & MULTIBOOT_LOADER_SHDR) { + tmp = mbi->shdr_num * mbi->shdr_size; + biosmem_register_boot_data(mbi->shdr_addr, mbi->shdr_addr + tmp, FALSE); + + tmp = phystokv(mbi->shdr_addr); + + for (i = 0; i < mbi->shdr_num; i++) { + shdr = (struct elf_shdr *)(tmp + (i * mbi->shdr_size)); + + if ((shdr->type != ELF_SHT_SYMTAB) + && (shdr->type != ELF_SHT_STRTAB)) + continue; + + biosmem_register_boot_data(shdr->addr, shdr->addr + shdr->size, FALSE); + } + } +} + +#endif /* MACH_HYP */ + /* * Basic PC VM initialization. * Turns on paging and changes the kernel segments to use high linear addresses. @@ -301,6 +359,7 @@ i386at_init(void) #ifdef MACH_HYP biosmem_xen_bootstrap(); #else /* MACH_HYP */ + register_boot_data((struct multiboot_raw_info *) &boot_info); biosmem_bootstrap((struct multiboot_raw_info *) &boot_info); #endif /* MACH_HYP */ |