Home | History | Annotate | Line # | Download | only in efiboot
boot.c revision 1.7
      1 /*	$NetBSD: boot.c,v 1.7 2018/09/09 13:37:54 jmcneill Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2016 Kimihiro Nonaka <nonaka (at) netbsd.org>
      5  * Copyright (c) 2018 Jared McNeill <jmcneill (at) invisible.ca>
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27  * SUCH DAMAGE.
     28  */
     29 
     30 #include "efiboot.h"
     31 #include "efiblock.h"
     32 #include "efifdt.h"
     33 
     34 #include <sys/bootblock.h>
     35 #include <sys/boot_flag.h>
     36 #include <machine/limits.h>
     37 
     38 #include <loadfile.h>
     39 
     40 extern const char bootprog_name[], bootprog_rev[], bootprog_kernrev[];
     41 
     42 extern char twiddle_toggle;
     43 
     44 static const char * const names[][2] = {
     45 	{ "netbsd", "netbsd.gz" },
     46 	{ "onetbsd", "onetbsd.gz" },
     47 	{ "netbsd.old", "netbsd.old.gz" },
     48 };
     49 
     50 #define NUMNAMES	__arraycount(names)
     51 #define DEFFILENAME	names[0][0]
     52 
     53 #define	DEFTIMEOUT	5
     54 
     55 static char default_device[32];
     56 static char initrd_path[255];
     57 static char dtb_path[255];
     58 
     59 void	command_boot(char *);
     60 void	command_dev(char *);
     61 void	command_dtb(char *);
     62 void	command_initrd(char *);
     63 void	command_ls(char *);
     64 void	command_reset(char *);
     65 void	command_version(char *);
     66 void	command_quit(char *);
     67 
     68 const struct boot_command commands[] = {
     69 	{ "boot",	command_boot,		"boot [dev:][filename] [args]\n     (ex. \"hd0a:\\netbsd.old -s\"" },
     70 	{ "dev",	command_dev,		"dev" },
     71 	{ "dtb",	command_dtb,		"dtb [dev:][filename]" },
     72 	{ "initrd",	command_initrd,		"initrd [dev:][filename]" },
     73 	{ "ls",		command_ls,		"ls [hdNn:/path]" },
     74 	{ "version",	command_version,	"version" },
     75 	{ "help",	command_help,		"help|?" },
     76 	{ "?",		command_help,		NULL },
     77 	{ "quit",	command_quit,		"quit" },
     78 	{ NULL,		NULL },
     79 };
     80 
     81 void
     82 command_help(char *arg)
     83 {
     84 	int n;
     85 
     86 	printf("commands are:\n");
     87 	for (n = 0; commands[n].c_name; n++) {
     88 		if (commands[n].c_help)
     89 			printf("%s\n", commands[n].c_help);
     90 	}
     91 }
     92 
     93 void
     94 command_boot(char *arg)
     95 {
     96 	char *fname = arg;
     97 	char *bootargs = gettrailer(arg);
     98 
     99 	exec_netbsd(*fname ? fname : DEFFILENAME, bootargs);
    100 }
    101 
    102 void
    103 command_dev(char *arg)
    104 {
    105 	if (arg && *arg) {
    106 		set_default_device(arg);
    107 	} else {
    108 		efi_block_show();
    109 		efi_net_show();
    110 		efi_pxe_show();
    111 	}
    112 
    113 	if (strlen(default_device) > 0) {
    114 		printf("\n");
    115 		printf("default: %s\n", default_device);
    116 	}
    117 }
    118 
    119 void
    120 command_dtb(char *arg)
    121 {
    122 	set_dtb_path(arg);
    123 }
    124 
    125 void
    126 command_initrd(char *arg)
    127 {
    128 	set_initrd_path(arg);
    129 }
    130 
    131 void
    132 command_ls(char *arg)
    133 {
    134 	ls(arg);
    135 }
    136 
    137 void
    138 command_version(char *arg)
    139 {
    140 	char *ufirmware;
    141 	int rv;
    142 
    143 	printf("EFI version: %d.%02d\n",
    144 	    ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff);
    145 	ufirmware = NULL;
    146 	rv = ucs2_to_utf8(ST->FirmwareVendor, &ufirmware);
    147 	if (rv == 0) {
    148 		printf("EFI Firmware: %s (rev %d.%02d)\n", ufirmware,
    149 		    ST->FirmwareRevision >> 16,
    150 		    ST->FirmwareRevision & 0xffff);
    151 		FreePool(ufirmware);
    152 	}
    153 
    154 	efi_fdt_show();
    155 }
    156 
    157 void
    158 command_quit(char *arg)
    159 {
    160 	efi_exit();
    161 }
    162 
    163 int
    164 set_default_device(char *arg)
    165 {
    166 	if (strlen(arg) + 1 > sizeof(default_device))
    167 		return ERANGE;
    168 	strcpy(default_device, arg);
    169 	return 0;
    170 }
    171 
    172 char *
    173 get_default_device(void)
    174 {
    175 	return default_device;
    176 }
    177 
    178 int
    179 set_initrd_path(char *arg)
    180 {
    181 	if (strlen(arg) + 1 > sizeof(initrd_path))
    182 		return ERANGE;
    183 	strcpy(initrd_path, arg);
    184 	return 0;
    185 }
    186 
    187 char *
    188 get_initrd_path(void)
    189 {
    190 	return initrd_path;
    191 }
    192 
    193 int
    194 set_dtb_path(char *arg)
    195 {
    196 	if (strlen(arg) + 1 > sizeof(dtb_path))
    197 		return ERANGE;
    198 	strcpy(dtb_path, arg);
    199 	return 0;
    200 }
    201 
    202 char *
    203 get_dtb_path(void)
    204 {
    205 	return dtb_path;
    206 }
    207 
    208 void
    209 print_banner(void)
    210 {
    211 	printf("\n\n"
    212 	    ">> %s, Revision %s (from NetBSD %s)\n",
    213 	    bootprog_name, bootprog_rev, bootprog_kernrev);
    214 }
    215 
    216 void
    217 boot(void)
    218 {
    219 	int currname, c;
    220 
    221 	print_banner();
    222 
    223 	printf("Press return to boot now, any other key for boot prompt\n");
    224 	for (currname = 0; currname < NUMNAMES; currname++) {
    225 		printf("booting %s - starting in ", names[currname][0]);
    226 
    227 		c = awaitkey(DEFTIMEOUT, 1);
    228 		if ((c != '\r') && (c != '\n') && (c != '\0')) {
    229 			bootprompt(); /* does not return */
    230 		}
    231 
    232 		/*
    233 		 * try pairs of names[] entries, foo and foo.gz
    234 		 */
    235 		exec_netbsd(names[currname][0], "");
    236 		exec_netbsd(names[currname][1], "");
    237 	}
    238 
    239 	bootprompt();	/* does not return */
    240 }
    241