#include <stand.h>
#include <sys/param.h>
#include <sys/reboot.h>
#include <sys/linker.h>
#include <i386/include/bootinfo.h>
#include "bootstrap.h"
#include "modinfo.h"
#include "libuserboot.h"
#ifdef LOADER_GELI_SUPPORT
#include "geliboot.h"
#endif
static struct bootinfo bi;
int
bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t *modulep, vm_offset_t *kernendp)
{
struct preloaded_file *xp, *kfp;
struct devdesc *rootdev;
struct file_metadata *md;
vm_offset_t addr;
vm_offset_t kernend;
vm_offset_t envp;
vm_offset_t size;
vm_offset_t ssym, esym;
char *rootdevname;
int bootdevnr, howto;
char *kernelname;
const char *kernelpath;
uint64_t lowmem, highmem;
howto = bi_getboothowto(args);
rootdevname = getenv("rootdev");
userboot_getdev((void **)(&rootdev), rootdevname, NULL);
if (rootdev == NULL) {
printf("can't determine root device\n");
return(EINVAL);
}
getrootmount(devformat(rootdev));
bootdevnr = 0;
#if 0
if (bootdevnr == -1) {
printf("root device %s invalid\n", devformat(rootdev));
return (EINVAL);
}
#endif
free(rootdev);
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;
}
addr = md_align(addr);
envp = addr;
addr = md_copyenv(addr);
addr = md_align(addr);
kfp = file_findfile(NULL, md_kerntype);
if (kfp == NULL)
panic("can't find kernel file");
kernend = 0;
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);
#ifdef LOADER_GELI_SUPPORT
geli_export_key_metadata(kfp);
#endif
*modulep = addr;
size = md_copymodules(0, false);
kernend = md_align(addr + size);
*kernendp = kernend;
md = file_findmetadata(kfp, MODINFOMD_KERNEND);
bcopy(&kernend, md->md_data, sizeof kernend);
(void)md_copymodules(addr, false);
ssym = esym = 0;
md = file_findmetadata(kfp, MODINFOMD_SSYM);
if (md != NULL)
ssym = *((vm_offset_t *)&(md->md_data));
md = file_findmetadata(kfp, MODINFOMD_ESYM);
if (md != NULL)
esym = *((vm_offset_t *)&(md->md_data));
if (ssym == 0 || esym == 0)
ssym = esym = 0;
kernelname = getenv("kernelname");
userboot_getdev(NULL, kernelname, &kernelpath);
bi.bi_version = BOOTINFO_VERSION;
bi.bi_size = sizeof(bi);
CALLBACK(getmem, &lowmem, &highmem);
bi.bi_memsizes_valid = 1;
bi.bi_basemem = 640;
bi.bi_extmem = (lowmem - 0x100000) / 1024;
bi.bi_envp = envp;
bi.bi_modulep = *modulep;
bi.bi_kernend = kernend;
bi.bi_symtab = ssym;
bi.bi_esymtab = esym;
bi.bi_kernelname = 0x2000 + sizeof(bi);
CALLBACK(copyin, &bi, 0x2000, sizeof(bi));
CALLBACK(copyin, kernelname, 0x2000 + sizeof(bi), strlen(kernelname) + 1);
*howtop = howto | RB_BOOTINFO;
*bootdevp = bootdevnr;
*bip = 0x2000;
return(0);
}