コード例 #1
0
ファイル: bootinfo.c プロジェクト: dcui/FreeBSD-9.3_kernel
/*
 * 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));
}
コード例 #2
0
ファイル: bootinfo.c プロジェクト: Alkzndr/freebsd
/*
 * 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);
}
コード例 #3
0
ファイル: bootinfo.c プロジェクト: UnitedMarsupials/kame
/*
 * 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);
}
コード例 #4
0
ファイル: bootinfo.c プロジェクト: ChristosKa/freebsd
/*
 * 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);
}