FreeBSD/sys/boot/i386/libi386/bootinfo32.c
/*
 * Load the information expected by an i386 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.
 */
Load the information expected by an i386 kernel.
Load the information expected by an i386 kernel .
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 i386_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, i, howto;
    char			*kernelname;
    const char			*kernelpath;
    howto = bi_getboothowto(args);
    rootdevname = getenv("rootdev");
    i386_getdev((void **)(&rootdev), rootdevname, NULL);
    if (rootdev == NULL) {		
	printf("can't determine root device\n");
	return(EINVAL);
    }
    getrootmount(i386_fmtdev((void *)rootdev));
    bootdevnr = 0;
    switch(rootdev->d_type) {
    case DEVT_CD:
	    bi.bi_bios_dev = bc_unit2bios(rootdev->d_unit);
	    bootdevnr = bc_getdev(rootdev);
	    break;
    case DEVT_DISK:
	bi.bi_bios_dev = bd_unit2bios(rootdev->d_unit);
	bootdevnr = bd_getdev(rootdev);
	break;
    case DEVT_NET:
    case DEVT_ZFS:
	    break;
    default:
	printf("WARNING - don't know how to boot from device type %d\n", rootdev->d_type);
    }
    if (bootdevnr == -1) {
	printf("root device %s invalid\n", i386_fmtdev(rootdev));
	return (EINVAL);
    }
    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 = roundup(addr, PAGE_SIZE);
    envp = addr;
    addr = bi_copyenv(addr);
    addr = roundup(addr, PAGE_SIZE);
    kfp = file_findfile(NULL, "elf kernel");
    if (kfp == NULL)
      kfp = file_findfile(NULL, "elf32 kernel");
    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);
    *modulep = addr;
    size = bi_copymodules32(0);
    kernend = roundup(addr + size, PAGE_SIZE);
    *kernendp = kernend;
    md = file_findmetadata(kfp, MODINFOMD_KERNEND);
    bcopy(&kernend, md->md_data, sizeof kernend);
    (void)bi_copymodules32(addr);
    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");
    i386_getdev(NULL, kernelname, &kernelpath);
    bi.bi_version = BOOTINFO_VERSION;
    bi.bi_kernelname = 0;		
    bi.bi_nfs_diskless = 0;		
    bi.bi_n_bios_used = 0;		
    for (i = 0; i < N_BIOS_GEOM; i++)
        bi.bi_bios_geom[i] = bd_getbigeom(i);
    bi.bi_size = sizeof(bi);
    bi.bi_memsizes_valid = 1;
    bi.bi_basemem = bios_basemem / 1024;
    bi.bi_extmem = bios_extmem / 1024;
    bi.bi_envp = envp;
    bi.bi_modulep = *modulep;
    bi.bi_kernend = kernend;
    bi.bi_kernelname = VTOP(kernelpath);
    bi.bi_symtab = ssym;       
    bi.bi_esymtab = esym;
    *howtop = howto | RB_BOOTINFO;
    *bootdevp = bootdevnr;
    *bip = VTOP(&bi);
    return(0);
}
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 i386_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 , i , howto ; char * kernelname ; const char * kernelpath ; howto = bi_getboothowto ( args ) ; rootdevname = getenv ( " " ) ; i386_getdev ( ( void * * ) ( & rootdev ) , rootdevname , NULL ) ; if ( rootdev == NULL ) { printf ( " \n " ) ; return ( EINVAL ) ; } getrootmount ( i386_fmtdev ( ( void * ) rootdev ) ) ; bootdevnr = 0 ; switch ( rootdev -> d_type ) { case DEVT_CD : bi . bi_bios_dev = bc_unit2bios ( rootdev -> d_unit ) ; bootdevnr = bc_getdev ( rootdev ) ; break ; case DEVT_DISK : bi . bi_bios_dev = bd_unit2bios ( rootdev -> d_unit ) ; bootdevnr = bd_getdev ( rootdev ) ; break ; case DEVT_NET : case DEVT_ZFS : break ; default : printf ( " \n " , rootdev -> d_type ) ; } if ( bootdevnr == -1 ) { printf ( " \n " , i386_fmtdev ( rootdev ) ) ; return ( EINVAL ) ; } 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 = roundup ( addr , PAGE_SIZE ) ; envp = addr ; addr = bi_copyenv ( addr ) ; addr = roundup ( addr , PAGE_SIZE ) ; kfp = file_findfile ( NULL , " " ) ; if ( kfp == NULL ) kfp = file_findfile ( NULL , " " ) ; if ( kfp == NULL ) panic ( " " ) ; 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 ) ; * modulep = addr ; size = bi_copymodules32 ( 0 ) ; kernend = roundup ( addr + size , PAGE_SIZE ) ; * kernendp = kernend ; md = file_findmetadata ( kfp , MODINFOMD_KERNEND ) ; bcopy ( & kernend , md -> md_data , sizeof kernend ) ; ( void ) bi_copymodules32 ( addr ) ; 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 ( " " ) ; i386_getdev ( NULL , kernelname , & kernelpath ) ; bi . bi_version = BOOTINFO_VERSION ; bi . bi_kernelname = 0 ; bi . bi_nfs_diskless = 0 ; bi . bi_n_bios_used = 0 ; for ( i = 0 ; i < N_BIOS_GEOM ; i ++ ) bi . bi_bios_geom [ i ] = bd_getbigeom ( i ) ; bi . bi_size = sizeof ( bi ) ; bi . bi_memsizes_valid = 1 ; bi . bi_basemem = bios_basemem / 1024 ; bi . bi_extmem = bios_extmem / 1024 ; bi . bi_envp = envp ; bi . bi_modulep = * modulep ; bi . bi_kernend = kernend ; bi . bi_kernelname = VTOP ( kernelpath ) ; bi . bi_symtab = ssym ; bi . bi_esymtab = esym ; * howtop = howto | RB_BOOTINFO ; * bootdevp = bootdevnr ; * bip = VTOP ( & bi ) ; return ( 0 ) ; }
Load the information expected by an i386 kernel.
Load the information expected by an i386 kernel .
/* 
     * 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.
     */ /* bad $rootdev/$currdev */ /* Try reading the /etc/fstab file to select the root device */ /* Do legacy rootdev guessing */ /* XXX - use a default bootdev of 0.  Is this ok??? */ /* Pass in BIOS device number. */ /* pass in the BIOS device number of the current disk */ /* find the last module in the chain */ /* pad to a page boundary */ /* copy our environment */ /* pad to a page boundary */ /* fill it in later */ /* Figure out the size and location of the metadata */ /* patch MODINFOMD_KERNEND */ /* copy module list and metadata */ /* sanity */ /* legacy bootinfo structure */ /* XXX char * -> kernel name */ /* struct nfs_diskless * */ /* XXX would have to hook biosdisk driver for these */ /* XXX this is only the primary kernel symtab */ /* legacy boot arguments */