diff options
Diffstat (limited to 'sys/boot/i386/libi386/bootinfo64.c')
-rw-r--r-- | sys/boot/i386/libi386/bootinfo64.c | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/sys/boot/i386/libi386/bootinfo64.c b/sys/boot/i386/libi386/bootinfo64.c index 617414e..751e806 100644 --- a/sys/boot/i386/libi386/bootinfo64.c +++ b/sys/boot/i386/libi386/bootinfo64.c @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include <sys/linker.h> #include <machine/bootinfo.h> #include <machine/cpufunc.h> +#include <machine/metadata.h> #include <machine/psl.h> #include <machine/specialreg.h> #include "bootstrap.h" @@ -176,14 +177,15 @@ bi_checkcpu(void) * - Module metadata are formatted and placed in kernel space. */ int -bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernendp) +bi_load64(char *args, vm_offset_t addr, vm_offset_t *modulep, + vm_offset_t *kernendp, int add_smap) { struct preloaded_file *xp, *kfp; struct i386_devdesc *rootdev; struct file_metadata *md; - vm_offset_t addr; u_int64_t kernend; u_int64_t envp; + u_int64_t module; vm_offset_t size; char *rootdevname; int howto; @@ -210,21 +212,18 @@ bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernendp) /* Try reading the /etc/fstab file to select the root device */ getrootmount(i386_fmtdev((void *)rootdev)); - /* find the last module in the chain */ - addr = 0; - for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { - if (addr < (xp->f_addr + xp->f_size)) - addr = xp->f_addr + xp->f_size; + if (addr == 0) { + /* find the last module in the chain */ + for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { + if (addr < (xp->f_addr + xp->f_size)) + addr = xp->f_addr + xp->f_size; + } } /* pad to a page boundary */ addr = roundup(addr, PAGE_SIZE); - /* copy our environment */ - envp = addr; - addr = bi_copyenv(addr); - - /* pad to a page boundary */ - addr = roundup(addr, PAGE_SIZE); + /* place the metadata before anything */ + module = *modulep = addr; kfp = file_findfile(NULL, "elf kernel"); if (kfp == NULL) @@ -235,20 +234,30 @@ bi_load64(char *args, vm_offset_t *modulep, vm_offset_t *kernendp) file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto); file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp); file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend); - bios_addsmapdata(kfp); + file_addmetadata(kfp, MODINFOMD_MODULEP, sizeof module, &module); + if (add_smap != 0) + bios_addsmapdata(kfp); - /* Figure out the size and location of the metadata */ - *modulep = addr; size = bi_copymodules64(0); - kernend = roundup(addr + size, PAGE_SIZE); + + /* copy our environment */ + envp = roundup(addr + size, PAGE_SIZE); + addr = bi_copyenv(envp); + + /* set kernend */ + kernend = roundup(addr, PAGE_SIZE); *kernendp = kernend; /* patch MODINFOMD_KERNEND */ md = file_findmetadata(kfp, MODINFOMD_KERNEND); bcopy(&kernend, md->md_data, sizeof kernend); + /* patch MODINFOMD_ENVP */ + md = file_findmetadata(kfp, MODINFOMD_ENVP); + bcopy(&envp, md->md_data, sizeof envp); + /* copy module list and metadata */ - (void)bi_copymodules64(addr); + (void)bi_copymodules64(*modulep); return(0); } |