1 /* $NetBSD: main.c,v 1.20 2009/03/21 15:01:56 ad Exp $ */ 2 3 /* 4 * Copyright (c) 1996 5 * Matthias Drochner. All rights reserved. 6 * Copyright (c) 1996 7 * Perry E. Metzger. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgements: 19 * This product includes software developed for the NetBSD Project 20 * by Matthias Drochner. 21 * This product includes software developed for the NetBSD Project 22 * by Perry E. Metzger. 23 * 4. The names of the authors may not be used to endorse or promote products 24 * derived from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 */ 38 39 #include <sys/types.h> 40 #include <sys/reboot.h> 41 #include <sys/bootblock.h> 42 43 #include <lib/libkern/libkern.h> 44 45 #include <lib/libsa/stand.h> 46 47 #include <libi386.h> 48 #include <bootmenu.h> 49 #include <bootmod.h> 50 #include "pxeboot.h" 51 52 extern struct x86_boot_params boot_params; 53 54 int errno; 55 int debug; 56 57 extern char bootprog_name[], bootprog_rev[], bootprog_kernrev[]; 58 59 int main(void); 60 61 void command_help(char *); 62 void command_quit(char *); 63 void command_boot(char *); 64 void command_consdev(char *); 65 void command_modules(char *); 66 67 const struct bootblk_command commands[] = { 68 { "help", command_help }, 69 { "?", command_help }, 70 { "quit", command_quit }, 71 { "boot", command_boot }, 72 { "consdev", command_consdev }, 73 { "modules", command_modules }, 74 { "load", module_add }, 75 { NULL, NULL }, 76 }; 77 78 static void 79 clearit(void) 80 { 81 82 if (bootconf.clear) 83 clear_pc_screen(); 84 } 85 86 static int 87 bootit(const char *filename, int howto) 88 { 89 if (exec_netbsd(filename, 0, howto, 0, clearit) < 0) 90 printf("boot: %s\n", strerror(errno)); 91 else 92 printf("boot returned\n"); 93 return (-1); 94 } 95 96 static void 97 print_banner(void) 98 { 99 int base = getbasemem(); 100 int ext = getextmem(); 101 102 clearit(); 103 printf("\n" 104 ">> NetBSD/x86 PXE boot, Revision %s (from NetBSD %s)\n" 105 ">> Memory: %d/%d k\n", 106 bootprog_rev, bootprog_kernrev, 107 base, ext); 108 } 109 110 int 111 main(void) 112 { 113 extern char twiddle_toggle; 114 char c; 115 116 twiddle_toggle = 1; /* no twiddling until we're ready */ 117 118 #ifdef SUPPORT_SERIAL 119 initio(SUPPORT_SERIAL); 120 #else 121 initio(CONSDEV_PC); 122 #endif 123 gateA20(); 124 125 #ifndef SMALL 126 parsebootconf(BOOTCONF); 127 128 /* 129 * If console set in boot.cfg, switch to it. 130 * This will print the banner, so we don't need to explicitly do it 131 */ 132 if (bootconf.consdev) 133 command_consdev(bootconf.consdev); 134 else 135 print_banner(); 136 137 /* Display the menu, if applicable */ 138 twiddle_toggle = 0; 139 if (bootconf.nummenu > 0) { 140 /* Does not return */ 141 doboottypemenu(); 142 } 143 #else 144 twiddle_toggle = 0; 145 print_banner(); 146 #endif 147 148 printf("Press return to boot now, any other key for boot menu\n"); 149 printf("booting netbsd - starting in "); 150 151 #ifdef SMALL 152 c = awaitkey(boot_params.bp_timeout, 1); 153 #else 154 c = awaitkey((bootconf.timeout < 0) ? 0 : bootconf.timeout, 1); 155 #endif 156 if ((c != '\r') && (c != '\n') && (c != '\0') && 157 ((boot_params.bp_flags & X86_BP_FLAGS_PASSWORD) == 0 158 || check_password((char *)boot_params.bp_password))) { 159 printf("type \"?\" or \"help\" for help.\n"); 160 bootmenu(); /* does not return */ 161 } 162 163 /* 164 * The file name provided here is just a default. If the 165 * DHCP server provides a file name, we'll use that instead. 166 */ 167 bootit("netbsd", 0); 168 169 /* 170 * If that fails, let the BIOS try the next boot device. 171 */ 172 return (1); 173 } 174 175 /* ARGSUSED */ 176 void 177 command_help(char *arg) 178 { 179 printf("commands are:\n" 180 "boot [filename] [-adsqv]\n" 181 " (ex. \"netbsd.old -s\"\n" 182 "consdev {pc|com[0123]|com[0123]kbd|auto}\n" 183 "modules {enabled|disabled}\n" 184 "load {path_to_module}\n" 185 "help|?\n" 186 "quit\n"); 187 } 188 189 /* ARGSUSED */ 190 void 191 command_quit(char *arg) 192 { 193 194 printf("Exiting...\n"); 195 delay(1000000); 196 reboot(); 197 /* Note: we shouldn't get to this point! */ 198 panic("Could not reboot!"); 199 exit(0); 200 } 201 202 void 203 command_boot(char *arg) 204 { 205 char *filename; 206 int howto; 207 208 if (parseboot(arg, &filename, &howto)) 209 bootit(filename, howto); 210 } 211 212 static const struct cons_devs { 213 const char *name; 214 u_int tag; 215 } cons_devs[] = { 216 { "pc", CONSDEV_PC }, 217 { "com0", CONSDEV_COM0 }, 218 { "com1", CONSDEV_COM1 }, 219 { "com2", CONSDEV_COM2 }, 220 { "com3", CONSDEV_COM3 }, 221 { "com0kbd", CONSDEV_COM0KBD }, 222 { "com1kbd", CONSDEV_COM1KBD }, 223 { "com2kbd", CONSDEV_COM2KBD }, 224 { "com3kbd", CONSDEV_COM3KBD }, 225 { "auto", CONSDEV_AUTO }, 226 { 0, 0 } }; 227 228 void 229 command_consdev(char *arg) 230 { 231 const struct cons_devs *cdp; 232 233 for (cdp = cons_devs; cdp->name; cdp++) { 234 if (!strcmp(arg, cdp->name)) { 235 initio(cdp->tag); 236 print_banner(); 237 return; 238 } 239 } 240 printf("invalid console device.\n"); 241 } 242 void 243 command_modules(char *arg) 244 { 245 if (strcmp(arg, "enabled") == 0 || 246 strcmp(arg, "on") == 0) 247 boot_modules_enabled = true; 248 else if (strcmp(arg, "disabled") == 0 || 249 strcmp(arg, "off") == 0) 250 boot_modules_enabled = false; 251 else 252 printf("invalid flag, must be 'enabled' or 'disabled'.\n"); 253 } 254