1/* $NetBSD: boot.c,v 1.2.2.2 2012/11/18 19:05:21 riz Exp $ */ 2 3/* 4 * Copyright (c) 2001 Minoura Makoto 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/param.h> 30#include <machine/bootinfo.h> 31 32#include <lib/libsa/stand.h> 33#include <lib/libsa/loadfile.h> 34#include <lib/libsa/ufs.h> 35#include <lib/libsa/dev_net.h> 36#include <lib/libkern/libkern.h> 37 38#include "libx68k.h" 39#include "iocs.h" 40 41#include "exec_image.h" 42 43 44#define HEAP_START ((void*) 0x00080000) 45#define HEAP_END ((void*) 0x000fffff) 46#define EXSCSI_BDID ((void*) 0x00ea0001) 47#define SRAM_MEMSIZE (*((long*) 0x00ed0008)) 48 49char default_kernel[20] = "nfs:netbsd"; 50int mpu; 51int console_device = -1; 52 53#ifdef DEBUG 54int debug = 1; 55#endif 56 57static void help(void); 58static void doboot(const char *, int); 59static void boot(char *); 60int bootmenu(void); 61void bootmain(int); 62extern int detectmpu(void); 63extern int badbaddr(void *); 64 65static void 66help(void) 67{ 68 printf("Usage:\n"); 69 printf("boot [dev:][file] -[flags]\n"); 70 printf(" dev: nfs, first probed NE2000 is used.\n"); 71 printf(" file: netbsd, netbsd.gz, etc.\n"); 72 printf(" flags: abdqsv\n"); 73 printf("halt\nreboot\n"); 74} 75 76static void 77doboot(const char *file, int flags) 78{ 79 u_long marks[MARK_MAX]; 80 int fd; 81 int dev, unit, part; 82 char *name; 83 short *p; 84 int loadflag; 85 86 printf("Starting %s, flags 0x%x\n", file, flags); 87 88 loadflag = LOAD_KERNEL; 89 if (file[0] == 'f') 90 loadflag &= ~LOAD_BACKWARDS; 91 92 marks[MARK_START] = 0x100000; 93 if ((fd = loadfile(file, marks, loadflag)) == -1) { 94 printf("loadfile failed\n"); 95 return; 96 } 97 close(fd); 98 99 if (devparse(file, &dev, &unit, &part, &name) != 0) { 100 printf("XXX: unknown corruption in /boot.\n"); 101 } 102 103 printf("dev = %x, unit = %d, name = %s\n", 104 dev, unit, name); 105 106 dev = X68K_MAKEBOOTDEV(X68K_MAJOR_NE, unit, 0); 107 printf("boot device = %x\n", dev); 108 printf("if = %d, unit = %d\n", 109 B_X68K_SCSI_IF(dev), 110 B_X68K_SCSI_IF_UN(dev)); 111 112 p = ((short*) marks[MARK_ENTRY]) - 1; 113 printf("Kernel Version: 0x%x\n", *p); 114 if (*p != 0x4e73 && *p != 0) { 115 /* 116 * XXX temporary solution; compatibility loader 117 * must be written. 118 */ 119 printf("This kernel is too new to be loaded by " 120 "this version of /boot.\n"); 121 return; 122 } 123 124 exec_image(marks[MARK_START], 0, marks[MARK_ENTRY]-marks[MARK_START], 125 marks[MARK_END]-marks[MARK_START], dev, flags); 126 127 return; 128} 129 130static void 131boot(char *arg) 132{ 133 char filename[80]; 134 char *p; 135 int flags = 0; 136 137 if (*arg == 0 || *arg == '-') { 138 strcpy(filename, default_kernel); 139 if (*arg == '-') 140 if (parseopts(arg, &flags) == 0) { 141 help(); 142 return; 143 } 144 doboot(filename, flags); 145 return; 146 } else { 147 p = gettrailer(arg); 148 if (strchr(arg, ':')) { 149 strcpy(filename, arg); 150 if (arg[strlen(arg) - 1] == ':') 151 strcat(filename, "netbsd"); 152 } else { 153 strcpy(filename, default_kernel); 154 strcpy(strchr(filename, ':') + 1, arg); 155 } 156 if (*p == '-') { 157 if (parseopts(p, &flags) == 0) 158 return; 159 } else if (*p != 0) { 160 help(); 161 return; 162 } 163 164 doboot(filename, flags); 165 return; 166 } 167} 168 169int 170bootmenu(void) 171{ 172 char input[80]; 173 int n = 5, c; 174 175 printf("Press return to boot now, any other key for boot menu\n"); 176 printf("booting %s - starting in %d seconds. ", 177 default_kernel, n); 178 while (n-- > 0 && (c = awaitkey_1sec()) == 0) { 179 printf("\r"); 180 printf("booting %s - starting in %d seconds. ", 181 default_kernel, n); 182 } 183 printf("\r"); 184 printf("booting %s - starting in %d seconds. ", default_kernel, 0); 185 printf("\n"); 186 187 if (c == 0 || c == '\r') { 188 doboot(default_kernel, 0); 189 printf("Could not start %s; ", default_kernel); 190 strcat(default_kernel, ".gz"); 191 printf("trying %s.\n", default_kernel); 192 doboot(default_kernel, 0); 193 printf("Could not start %s; ", default_kernel); 194 } 195 196 printf("Please use the absolute unit# (e.g. SCSI ID)" 197 " instead of the NetBSD logical #.\n"); 198 for (;;) { 199 char *p, *options; 200 201 printf("> "); 202 gets(input); 203 204 for (p = &input[0]; p - &input[0] < 80 && *p == ' '; p++) 205 ; 206 options = gettrailer(p); 207 if (strcmp("boot", p) == 0) 208 boot(options); 209 else if (strcmp("help", p) == 0 || strcmp("?", p) == 0) 210 help(); 211 else if (strcmp("halt", p) == 0 || strcmp("reboot", p) == 0) 212 exit(0); 213 else 214 printf("Unknown command %s\n", p); 215 } 216} 217 218 219extern const char bootprog_rev[]; 220extern const char bootprog_name[]; 221 222/* 223 * Arguments from the boot block: 224 * bootdev - specifies the device from which /boot was read, in 225 * bootdev format. 226 */ 227void 228bootmain(int bootdev) 229{ 230 mpu = detectmpu(); 231 rtc_offset = RTC_OFFSET; 232 try_bootp = 1; 233 234 if (mpu < 3) { /* not tested on 68020 */ 235 printf("This MPU cannot run NetBSD.\n"); 236 exit(1); 237 } 238 if (SRAM_MEMSIZE < 4*1024*1024) { 239 printf("Main memory too small.\n"); 240 exit(1); 241 } 242 243 console_device = consio_init(console_device); 244 setheap(HEAP_START, HEAP_END); 245 246 print_title("%s, Revision %s\n", bootprog_name, bootprog_rev); 247 bootmenu(); 248} 249