Beispiel #1
0
char *
userboot_fmtdev(void *vdev)
{
    struct disk_devdesc	*dev = (struct disk_devdesc *)vdev;
    static char		buf[128];	/* XXX device length constant? */

    switch(dev->d_type) {
    case DEVT_NONE:
	strcpy(buf, "(no device)");
	break;

    case DEVT_CD:
	sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
	break;

    case DEVT_DISK:
	return (disk_fmtdev(vdev));

    case DEVT_NET:
	sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
	break;

    case DEVT_ZFS:
#if defined(USERBOOT_ZFS_SUPPORT)
	return (zfs_fmtdev(vdev));
#else
	sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
#endif
	break;
    }
    return(buf);
}
Beispiel #2
0
char *
efi_fmtdev(void *vdev)
{
	struct devdesc *dev = (struct devdesc *)vdev;
	static char buf[SPECNAMELEN + 1];

	switch(dev->d_type) {
	case DEVT_NONE:
		strcpy(buf, "(no device)");
		break;

	case DEVT_DISK:
		return (disk_fmtdev(vdev));

#ifdef EFI_ZFS_BOOT
	case DEVT_ZFS:
		return (zfs_fmtdev(dev));
#endif
	default:
		sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
		break;
	}

	return (buf);
}
Beispiel #3
0
/*
 * Set the 'current device' by (if possible) recovering the boot device as 
 * supplied by the initial bootstrap.
 */
static void
extract_currdev(void)
{
	struct disk_devdesc dev;

	//bzero(&dev, sizeof(dev));

#if defined(USERBOOT_ZFS_SUPPORT)
	if (userboot_zfs_found) {
		struct zfs_devdesc zdev;
	
		/* Leave the pool/root guid's unassigned */
		bzero(&zdev, sizeof(zdev));
		zdev.d_dev = &zfs_dev;
		zdev.d_type = zdev.d_dev->dv_type;
		
		dev = *(struct disk_devdesc *)&zdev;
		init_zfs_bootenv(zfs_fmtdev(&dev));
	} else
#endif

	if (userboot_disk_maxunit > 0) {
		dev.d_dev = &userboot_disk;
		dev.d_type = dev.d_dev->dv_type;
		dev.d_unit = 0;
		dev.d_slice = 0;
		dev.d_partition = 0;
		/*
		 * If we cannot auto-detect the partition type then
		 * access the disk as a raw device.
		 */
		if (dev.d_dev->dv_open(NULL, &dev)) {
			dev.d_slice = -1;
			dev.d_partition = -1;
		}
	} else {
		dev.d_dev = &host_dev;
		dev.d_type = dev.d_dev->dv_type;
		dev.d_unit = 0;
	}

	env_setenv("currdev", EV_VOLATILE, userboot_fmtdev(&dev),
	    userboot_setcurrdev, env_nounset);
	env_setenv("loaddev", EV_VOLATILE, userboot_fmtdev(&dev),
	    env_noset, env_nounset);
}
Beispiel #4
0
char *
i386_fmtdev(void *vdev)
{
    struct i386_devdesc	*dev = (struct i386_devdesc *)vdev;
    static char		buf[128];	/* XXX device length constant? */
    char		*cp;

    switch(dev->d_type) {
    case DEVT_NONE:
        strcpy(buf, "(no device)");
        break;

    case DEVT_CD:
        sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
        break;

    case DEVT_DISK:
        cp = buf;
        cp += sprintf(cp, "%s%d", dev->d_dev->dv_name, dev->d_unit);
#ifdef LOADER_GPT_SUPPORT
        if (dev->d_kind.biosdisk.partition == 0xff) {
            cp += sprintf(cp, "p%d", dev->d_kind.biosdisk.slice);
        } else {
#endif
            if (dev->d_kind.biosdisk.slice > 0)
                cp += sprintf(cp, "s%d", dev->d_kind.biosdisk.slice);
            if (dev->d_kind.biosdisk.partition >= 0)
                cp += sprintf(cp, "%c", dev->d_kind.biosdisk.partition + 'a');
#ifdef LOADER_GPT_SUPPORT
        }
#endif
        strcat(cp, ":");
        break;

    case DEVT_NET:
        sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
        break;
    case DEVT_ZFS:
        return(zfs_fmtdev(vdev));
    }
    return(buf);
}
Beispiel #5
0
char *
i386_fmtdev(void *vdev)
{
    struct i386_devdesc	*dev = (struct i386_devdesc *)vdev;
    static char		buf[128];	/* XXX device length constant? */

    switch(dev->d_type) {
    case DEVT_NONE:
        strcpy(buf, "(no device)");
        break;

    case DEVT_CD:
    case DEVT_NET:
        sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
        break;

    case DEVT_DISK:
        return (disk_fmtdev(vdev));

    case DEVT_ZFS:
        return(zfs_fmtdev(vdev));
    }
    return(buf);
}
Beispiel #6
0
EFI_STATUS
main(int argc, CHAR16 *argv[])
{
	char var[128];
	EFI_LOADED_IMAGE *img;
	EFI_GUID *guid;
	int i, j, vargood, unit, howto;
	struct devsw *dev;
	uint64_t pool_guid;
	UINTN k;
	int has_kbd;

	archsw.arch_autoload = efi_autoload;
	archsw.arch_getdev = efi_getdev;
	archsw.arch_copyin = efi_copyin;
	archsw.arch_copyout = efi_copyout;
	archsw.arch_readin = efi_readin;
#ifdef EFI_ZFS_BOOT
	/* Note this needs to be set before ZFS init. */
	archsw.arch_zfs_probe = efi_zfs_probe;
#endif

	has_kbd = has_keyboard();

	/*
	 * XXX Chicken-and-egg problem; we want to have console output
	 * early, but some console attributes may depend on reading from
	 * eg. the boot device, which we can't do yet.  We can use
	 * printf() etc. once this is done.
	 */
	cons_probe();

	/*
	 * Initialise the block cache. Set the upper limit.
	 */
	bcache_init(32768, 512);

	/*
	 * Parse the args to set the console settings, etc
	 * boot1.efi passes these in, if it can read /boot.config or /boot/config
	 * or iPXE may be setup to pass these in.
	 *
	 * Loop through the args, and for each one that contains an '=' that is
	 * not the first character, add it to the environment.  This allows
	 * loader and kernel env vars to be passed on the command line.  Convert
	 * args from UCS-2 to ASCII (16 to 8 bit) as they are copied.
	 */
	howto = 0;
	for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-') {
			for (j = 1; argv[i][j] != 0; j++) {
				int ch;

				ch = argv[i][j];
				switch (ch) {
				case 'a':
					howto |= RB_ASKNAME;
					break;
				case 'd':
					howto |= RB_KDB;
					break;
				case 'D':
					howto |= RB_MULTIPLE;
					break;
				case 'h':
					howto |= RB_SERIAL;
					break;
				case 'm':
					howto |= RB_MUTE;
					break;
				case 'p':
					howto |= RB_PAUSE;
					break;
				case 'P':
					if (!has_kbd)
						howto |= RB_SERIAL | RB_MULTIPLE;
					break;
				case 'r':
					howto |= RB_DFLTROOT;
					break;
				case 's':
					howto |= RB_SINGLE;
					break;
				case 'S':
					if (argv[i][j + 1] == 0) {
						if (i + 1 == argc) {
							setenv("comconsole_speed", "115200", 1);
						} else {
							cp16to8(&argv[i + 1][0], var,
							    sizeof(var));
							setenv("comconsole_speedspeed", var, 1);
						}
						i++;
						break;
					} else {
						cp16to8(&argv[i][j + 1], var,
						    sizeof(var));
						setenv("comconsole_speed", var, 1);
						break;
					}
				case 'v':
					howto |= RB_VERBOSE;
					break;
				}
			}
		} else {
			vargood = 0;
			for (j = 0; argv[i][j] != 0; j++) {
				if (j == sizeof(var)) {
					vargood = 0;
					break;
				}
				if (j > 0 && argv[i][j] == '=')
					vargood = 1;
				var[j] = (char)argv[i][j];
			}
			if (vargood) {
				var[j] = 0;
				putenv(var);
			}
		}
	}
	for (i = 0; howto_names[i].ev != NULL; i++)
		if (howto & howto_names[i].mask)
			setenv(howto_names[i].ev, "YES", 1);
	if (howto & RB_MULTIPLE) {
		if (howto & RB_SERIAL)
			setenv("console", "comconsole efi" , 1);
		else
			setenv("console", "efi comconsole" , 1);
	} else if (howto & RB_SERIAL) {
		setenv("console", "comconsole" , 1);
	}

	if (efi_copy_init()) {
		printf("failed to allocate staging area\n");
		return (EFI_BUFFER_TOO_SMALL);
	}

	/*
	 * March through the device switch probing for things.
	 */
	for (i = 0; devsw[i] != NULL; i++)
		if (devsw[i]->dv_init != NULL)
			(devsw[i]->dv_init)();

	/* Get our loaded image protocol interface structure. */
	BS->HandleProtocol(IH, &imgid, (VOID**)&img);

	printf("Command line arguments:");
	for (i = 0; i < argc; i++) {
		printf(" ");
		print_str16(argv[i]);
	}
	printf("\n");

	printf("Image base: 0x%lx\n", (u_long)img->ImageBase);
	printf("EFI version: %d.%02d\n", ST->Hdr.Revision >> 16,
	    ST->Hdr.Revision & 0xffff);
	printf("EFI Firmware: ");
	/* printf doesn't understand EFI Unicode */
	ST->ConOut->OutputString(ST->ConOut, ST->FirmwareVendor);
	printf(" (rev %d.%02d)\n", ST->FirmwareRevision >> 16,
	    ST->FirmwareRevision & 0xffff);

	printf("\n");
	printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
	printf("(%s, %s)\n", bootprog_maker, bootprog_date);

	/*
	 * Disable the watchdog timer. By default the boot manager sets
	 * the timer to 5 minutes before invoking a boot option. If we
	 * want to return to the boot manager, we have to disable the
	 * watchdog timer and since we're an interactive program, we don't
	 * want to wait until the user types "quit". The timer may have
	 * fired by then. We don't care if this fails. It does not prevent
	 * normal functioning in any way...
	 */
	BS->SetWatchdogTimer(0, 0, 0, NULL);

	if (efi_handle_lookup(img->DeviceHandle, &dev, &unit, &pool_guid) != 0)
		return (EFI_NOT_FOUND);

	switch (dev->dv_type) {
#ifdef EFI_ZFS_BOOT
	case DEVT_ZFS: {
		struct zfs_devdesc currdev;

		currdev.d_dev = dev;
		currdev.d_unit = unit;
		currdev.d_type = currdev.d_dev->dv_type;
		currdev.d_opendata = NULL;
		currdev.pool_guid = pool_guid;
		currdev.root_guid = 0;
		env_setenv("currdev", EV_VOLATILE, efi_fmtdev(&currdev),
			   efi_setcurrdev, env_nounset);
		env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), env_noset,
			   env_nounset);
		init_zfs_bootenv(zfs_fmtdev(&currdev));
		break;
	}
#endif
	default: {
		struct devdesc currdev;

		currdev.d_dev = dev;
		currdev.d_unit = unit;
		currdev.d_opendata = NULL;
		currdev.d_type = currdev.d_dev->dv_type;
		env_setenv("currdev", EV_VOLATILE, efi_fmtdev(&currdev),
			   efi_setcurrdev, env_nounset);
		env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), env_noset,
			   env_nounset);
		break;
	}
	}

	setenv("LINES", "24", 1);	/* optional */

	for (k = 0; k < ST->NumberOfTableEntries; k++) {
		guid = &ST->ConfigurationTable[k].VendorGuid;
		if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) {
			smbios_detect(ST->ConfigurationTable[k].VendorTable);
			break;
		}
	}

	interact(NULL);			/* doesn't return */

	return (EFI_SUCCESS);		/* keep compiler happy */
}