/* * Load the information expected by the kernel. * * - The kernel environment is copied into kernel space. * - Module metadata are formatted and placed in kernel space. */ int bi_load(struct preloaded_file *fp, uint64_t *bi_addr) { struct bootinfo bi; struct preloaded_file *xp; struct file_metadata *md; struct devdesc *rootdev; char *rootdevname; vm_offset_t addr, ssym, esym; bzero(&bi, sizeof(struct bootinfo)); bi.bi_version = 1; // bi.bi_boothowto = bi_getboothowto(fp->f_args); /* * Allow the environment variable 'rootdev' to override the supplied * device. This should perhaps go to MI code and/or have $rootdev * tested/set by MI code before launching the kernel. */ rootdevname = getenv("rootdev"); i386_getdev((void**)&rootdev, rootdevname, NULL); if (rootdev != NULL) { /* Try reading /etc/fstab to select the root device. */ getrootmount(i386_fmtdev(rootdev)); free(rootdev); } md = file_findmetadata(fp, MODINFOMD_SSYM); ssym = (md != NULL) ? *((vm_offset_t *)&(md->md_data)) : 0; md = file_findmetadata(fp, MODINFOMD_ESYM); esym = (md != NULL) ? *((vm_offset_t *)&(md->md_data)) : 0; if (ssym != 0 && esym != 0) { bi.bi_symtab = ssym; bi.bi_esymtab = esym; } /* 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; } addr = (addr + 15) & ~15; /* Copy module list and metadata. */ bi.bi_modulep = addr; addr = bi_copymodules(addr); if (addr <= bi.bi_modulep) { addr = bi.bi_modulep; bi.bi_modulep = 0; } addr = (addr + 15) & ~15; /* Copy our environment. */ bi.bi_envp = addr; addr = bi_copyenv(addr); if (addr <= bi.bi_envp) { addr = bi.bi_envp; bi.bi_envp = 0; } addr = (addr + PAGE_MASK) & ~PAGE_MASK; bi.bi_kernend = addr; return (ldr_bootinfo(&bi, bi_addr)); }
/* * Load the information expected by an amd64 kernel. * * - The 'boothowto' argument is constructed. * - The 'bootdev' argument is constructed. * - The 'bootinfo' struct is constructed, and copied into the kernel space. * - The kernel environment is copied into kernel space. * - Module metadata are formatted and placed in kernel space. */ int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp) { struct preloaded_file *xp, *kfp; struct devdesc *rootdev; struct file_metadata *md; vm_offset_t addr; uint64_t kernend; uint64_t envp; vm_offset_t size; char *rootdevname; int howto; howto = bi_getboothowto(args); /* * Allow the environment variable 'rootdev' to override the supplied * device. This should perhaps go to MI code and/or have $rootdev * tested/set by MI code before launching the kernel. */ rootdevname = getenv("rootdev"); x86_efi_getdev((void**)(&rootdev), rootdevname, NULL); if (rootdev == NULL) { printf("Can't determine root device.\n"); return(EINVAL); } /* Try reading the /etc/fstab file to select the root device */ getrootmount(x86_efi_fmtdev((void *)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; } /* 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); kfp = file_findfile(NULL, "elf kernel"); if (kfp == NULL) kfp = file_findfile(NULL, "elf64 kernel"); if (kfp == NULL) panic("can't find kernel file"); kernend = 0; /* fill it in later */ file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto); file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp); file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend); bi_load_efi_data(kfp); /* Figure out the size and location of the metadata. */ *modulep = addr; size = bi_copymodules(0); kernend = roundup(addr + size, PAGE_SIZE); *kernendp = kernend; /* patch MODINFOMD_KERNEND */ md = file_findmetadata(kfp, MODINFOMD_KERNEND); bcopy(&kernend, md->md_data, sizeof kernend); /* Copy module list and metadata. */ (void)bi_copymodules(addr); return (0); }
/* * Load the information expected by an alpha kernel. * * - The kernel environment is copied into kernel space. * - Module metadata are formatted and placed in kernel space. */ int bi_load(struct bootinfo *bi, struct preloaded_file *fp, char *args) { char *rootdevname; struct ski_devdesc *rootdev; struct preloaded_file *xp; vm_offset_t addr, bootinfo_addr; u_int pad; char *kernelname; vm_offset_t ssym, esym; struct file_metadata *md; EFI_MEMORY_DESCRIPTOR *memp; /* * Version 1 bootinfo. */ bi->bi_magic = BOOTINFO_MAGIC; bi->bi_version = 1; /* * Calculate boothowto. */ bi->bi_boothowto = bi_getboothowto(fp->f_args); /* * Allow the environment variable 'rootdev' to override the supplied device * This should perhaps go to MI code and/or have $rootdev tested/set by * MI code before launching the kernel. */ rootdevname = getenv("rootdev"); ski_getdev((void **)(&rootdev), rootdevname, NULL); if (rootdev == NULL) { /* bad $rootdev/$currdev */ printf("can't determine root device\n"); return(EINVAL); } /* Try reading the /etc/fstab file to select the root device */ getrootmount(ski_fmtdev((void *)rootdev)); free(rootdev); ssym = esym = 0; if ((md = file_findmetadata(fp, MODINFOMD_SSYM)) != NULL) ssym = *((vm_offset_t *)&(md->md_data)); if ((md = file_findmetadata(fp, MODINFOMD_ESYM)) != NULL) esym = *((vm_offset_t *)&(md->md_data)); if (ssym == 0 || esym == 0) ssym = esym = 0; /* sanity */ bi->bi_symtab = ssym; bi->bi_esymtab = esym; /* 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; } /* pad to a page boundary */ pad = (u_int)addr & PAGE_MASK; if (pad != 0) { pad = PAGE_SIZE - pad; addr += pad; } /* copy our environment */ bi->bi_envp = addr; addr = bi_copyenv(addr); /* pad to a page boundary */ pad = (u_int)addr & PAGE_MASK; if (pad != 0) { pad = PAGE_SIZE - pad; addr += pad; } /* copy module list and metadata */ bi->bi_modulep = addr; addr = bi_copymodules(addr); /* all done copying stuff in, save end of loaded object space */ bi->bi_kernend = addr; /* Describe the SKI memory map. */ bi->bi_memmap = (u_int64_t)(bi + 1); bi->bi_memmap_size = 2 * sizeof(EFI_MEMORY_DESCRIPTOR); bi->bi_memdesc_size = sizeof(EFI_MEMORY_DESCRIPTOR); bi->bi_memdesc_version = 1; memp = (EFI_MEMORY_DESCRIPTOR *) bi->bi_memmap; memp[0].Type = EfiConventionalMemory; memp[0].PhysicalStart = 2L*1024*1024; memp[0].VirtualStart = 0; memp[0].NumberOfPages = (64L*1024*1024)>>12; memp[0].Attribute = EFI_MEMORY_WB; memp[1].Type = EfiMemoryMappedIOPortSpace; memp[1].PhysicalStart = 0xffffc000000; memp[1].VirtualStart = 0; memp[1].NumberOfPages = (64L*1024*1024)>>12; memp[1].Attribute = EFI_MEMORY_UC; return(0); }
/* * Load the information expected by the kernel. * * - The kernel environment is copied into kernel space. * - Module metadata are formatted and placed in kernel space. */ int ia64_bootinfo(struct preloaded_file *fp, struct bootinfo **res) { struct bootinfo bi; struct preloaded_file *xp; struct file_metadata *md; struct devdesc *rootdev; char *rootdevname; vm_offset_t addr, ssym, esym; int error; *res = NULL; bzero(&bi, sizeof(struct bootinfo)); bi.bi_magic = BOOTINFO_MAGIC; bi.bi_version = 1; bi.bi_boothowto = bi_getboothowto(fp->f_args); /* * Allow the environment variable 'rootdev' to override the supplied * device. This should perhaps go to MI code and/or have $rootdev * tested/set by MI code before launching the kernel. */ rootdevname = getenv("rootdev"); ia64_getdev((void**)&rootdev, rootdevname, NULL); if (rootdev != NULL) { /* Try reading /etc/fstab to select the root device. */ getrootmount(ia64_fmtdev(rootdev)); free(rootdev); } md = file_findmetadata(fp, MODINFOMD_SSYM); ssym = (md != NULL) ? *((vm_offset_t *)&(md->md_data)) : 0; md = file_findmetadata(fp, MODINFOMD_ESYM); esym = (md != NULL) ? *((vm_offset_t *)&(md->md_data)) : 0; if (ssym != 0 && esym != 0) { bi.bi_symtab = ssym; bi.bi_esymtab = esym; } /* 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; } addr = (addr + 15) & ~15; /* Copy module list and metadata. */ bi.bi_modulep = addr; addr = bi_copymodules(addr); if (addr <= bi.bi_modulep) { addr = bi.bi_modulep; bi.bi_modulep = 0; } addr = (addr + 15) & ~15; /* Copy our environment. */ bi.bi_envp = addr; addr = bi_copyenv(addr); if (addr <= bi.bi_envp) { addr = bi.bi_envp; bi.bi_envp = 0; } addr = (addr + 15) & ~15; bi.bi_kernend = addr; error = ia64_platform_bootinfo(&bi, res); if (error) return (error); if (IS_LEGACY_KERNEL()) { if (*res == NULL) return (EDOOFUS); bcopy(&bi, *res, sizeof(bi)); return (0); } bi.bi_pbvm_pgtbl = (uintptr_t)ia64_pgtbl; bi.bi_pbvm_pgtblsz = ia64_pgtblsz; ia64_copyin((void *)bi.bi_memmap, addr, bi.bi_memmap_size); bi.bi_memmap = addr; addr = (addr + bi.bi_memmap_size + 15) & ~15; bi.bi_kernend = addr + sizeof(bi); ia64_copyin(&bi, addr, sizeof(bi)); *res = (void *)addr; return (0); }