1 /* 2 * Copyright (c) 1992 OMRON Corporation. 3 * Copyright (c) 1992 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * OMRON Corporation. 8 * 9 * %sccs.include.redist.c% 10 * 11 * @(#)boot.c 7.3 (Berkeley) 05/12/93 12 */ 13 14 /* 15 * boot.c -- boot program 16 * by A.Fujita, MAR-01-1992 17 */ 18 19 #include <sys/param.h> 20 #include <sys/reboot.h> 21 #include <sys/exec.h> 22 #include <machine/stinger.h> 23 #include <luna68k/stand/saio.h> 24 #include <luna68k/stand/status.h> 25 26 extern struct KernInter *kiff; 27 28 int howto; 29 int devtype = MAKEBOOTDEV(4, 0, 6, 0, 0); 30 31 char *copyunix(); 32 33 struct exec header; 34 char default_file[] = "sd(0,0)vmunix"; 35 36 char *how_to_info[] = { 37 "RB_ASKNAME ask for file name to reboot from", 38 "RB_SINGLE reboot to single user only", 39 "RB_NOSYNC dont sync before reboot", 40 "RB_HALT don't reboot, just halt", 41 "RB_INITNAME name given for /etc/init (unused)", 42 "RB_DFLTROOT use compiled-in rootdev", 43 "RB_KDB give control to kernel debugger", 44 "RB_RDONLY mount root fs read-only" 45 }; 46 47 #define TAPE 48 #ifdef TAPE /* A.Kojima */ 49 extern dev_t rst0; 50 extern dev_t nrst0; 51 char *stcopyunix(); 52 #endif 53 54 int 55 how_to_boot(argc, argv) 56 int argc; 57 char *argv[]; 58 { 59 int i, h = howto; 60 61 if (argc < 2) { 62 printf("howto: 0x%s\n\n", hexstr(howto, 2)); 63 64 if (h == 0) { 65 printf("\t%s\n", "RB_AUTOBOOT flags for system auto-booting itself"); 66 } else { 67 for (i = 0; i < 8; i++, h >>= 1) { 68 if (h & 0x01) { 69 printf("\t%s\n", how_to_info[i]); 70 } 71 } 72 } 73 74 printf("\n"); 75 } 76 } 77 78 int 79 get_boot_device(s) 80 char *s; 81 { 82 register int unit = 0; 83 register int part = 0; 84 register char *p = s; 85 86 while (*p != '(') { 87 if (*p == '\0') 88 goto error; 89 p++; 90 } 91 92 while (*++p != ',') { 93 if (*p == '\0') 94 goto error; 95 if (*p >= '0' && *p <= '9') 96 unit = (unit * 10) + (*p - '0'); 97 } 98 99 while (*++p != ')') { 100 if (*p == '\0') 101 goto error; 102 if (*p >= '0' && *p <= '9') 103 part = (part * 10) + (*p - '0'); 104 } 105 106 return(MAKEBOOTDEV(4, 0, (6 - unit), unit, part)); 107 108 error: 109 return(MAKEBOOTDEV(4, 0, 6, 0, 0)); 110 } 111 112 int 113 boot(argc, argv) 114 int argc; 115 char *argv[]; 116 { 117 register int io; 118 char *line; 119 120 if (argc < 2) 121 line = default_file; 122 else 123 line = argv[1]; 124 125 devtype = get_boot_device(line); 126 127 printf("Booting %s\n", line); 128 129 #ifdef TAPE /* A.Kojima */ 130 if (!strcmp("st", argv[1])) { 131 io = argc < 3 ? 0 : *argv[2] - '0'; 132 printf("boot tape file number:%d\n", io); 133 stbootunix(howto, devtype, io); 134 return; 135 } 136 #endif 137 io = open(line, 0); 138 if (io >= 0) { 139 bootunix(howto, devtype, io); 140 close(io); 141 } 142 } 143 144 int 145 load(argc, argv) 146 int argc; 147 char *argv[]; 148 { 149 register int io; 150 char *line; 151 152 if (argc < 2) 153 line = default_file; 154 else 155 line = argv[1]; 156 157 printf("loading %s\n", line); 158 159 io = open(line, 0); 160 if (io >= 0) { 161 copyunix(io); 162 printf("\n"); 163 close(io); 164 } 165 } 166 167 int 168 bootunix(howto, devtype, io) 169 register howto; /* d7 contains boot flags */ 170 register devtype; /* d6 contains boot device */ 171 register io; 172 { 173 register char *load; /* a5 contains load addr for unix */ 174 175 load = copyunix(io); 176 177 printf(" start 0x%x\n", load); 178 asm(" movl %0,d7" : : "d" (howto)); 179 asm(" movl %0,d6" : : "d" (devtype)); 180 asm(" movl %0,a5" : : "a" (kiff)); 181 (*((int (*)()) load))(); 182 } 183 184 char * 185 copyunix(io) 186 register io; 187 { 188 189 register int i; 190 register char *load; /* a5 contains load addr for unix */ 191 register char *addr; 192 193 /* 194 * Read a.out file header 195 */ 196 197 i = read(io, (char *)&header, sizeof(struct exec)); 198 if (i != sizeof(struct exec) || 199 (header.a_magic != 0407 && header.a_magic != 0413 && header.a_magic != 0410)) { 200 printf("illegal magic number ... 0x%x\n"); 201 printf("Bad format\n"); 202 return(0); 203 } 204 205 load = addr = (char *) (header.a_entry & 0x00FFFFFF); 206 207 printf("%d", header.a_text); 208 if (header.a_magic == 0413 && lseek(io, 0x400, 0) == -1) 209 goto shread; 210 211 /* 212 * Load TEXT Segment 213 */ 214 215 if (read(io, (char *)addr, header.a_text) != header.a_text) 216 goto shread; 217 addr += header.a_text; 218 if (header.a_magic == 0413 || header.a_magic == 0410) 219 while ((int)addr & CLOFSET) 220 *addr++ = 0; 221 222 /* 223 * Load DATA Segment 224 */ 225 226 printf("+%d", header.a_data); 227 if (read(io, addr, header.a_data) != header.a_data) 228 goto shread; 229 230 /* 231 * Clear BSS Segment 232 */ 233 234 addr += header.a_data; 235 printf("+%d", header.a_bss); 236 header.a_bss += 128*512; /* slop */ 237 for (i = 0; i < header.a_bss; i++) 238 *addr++ = 0; 239 240 return(load); 241 242 shread: 243 printf(" Short read\n"); 244 return(0); 245 } 246 247 #ifdef TAPE /* A.Kojima */ 248 int 249 stbootunix(howto, devtype, skip) 250 register howto; /* d7 contains boot flags */ 251 register devtype; /* d6 contains boot device */ 252 register skip; /* tape skip */ 253 { 254 register int i; 255 register char *load; /* a5 contains load addr for unix */ 256 257 /* 258 * Tape rewind and skip 259 */ 260 st_rewind(rst0); 261 for (i = 0; i < skip; i++) { 262 st_skip(rst0); 263 } 264 265 load = stcopyunix(); 266 267 st_rewind(rst0); 268 269 printf(" start 0x%x\n", load); 270 asm(" movl %0,d7" : : "d" (howto)); 271 asm(" movl %0,d6" : : "d" (devtype)); 272 asm(" movl %0,a5" : : "a" (kiff)); 273 (*((int (*)()) load))(); 274 } 275 276 char * 277 stcopyunix() 278 { 279 280 register int i; 281 register char *load; /* a5 contains load addr for unix */ 282 register char *addr; 283 u_char buf[0x400]; 284 285 /* 286 * Read a.out file header 287 */ 288 289 i = tread(/*io,*/ (char *)&header, sizeof(struct exec)); 290 if (i != sizeof(struct exec) || 291 (header.a_magic != 0407 && header.a_magic != 0413 && header.a_magic != 0410)) { 292 printf("illegal magic number ... 0x%x\n"); 293 printf("Bad format\n"); 294 return(0); 295 } 296 297 load = addr = (char *) (header.a_entry & 0x00FFFFFF); 298 299 printf("%d", header.a_text); 300 301 i = 0x400 - i; 302 if (header.a_magic == 0413 && tread(buf, i) != i) { /* easy seek */ 303 goto shread; 304 } 305 306 /* 307 * Load TEXT Segment 308 */ 309 310 if (tread(/*io,*/ (char *)addr, header.a_text) != header.a_text) 311 goto shread; 312 addr += header.a_text; 313 if (header.a_magic == 0413 || header.a_magic == 0410) 314 while ((int)addr & CLOFSET) 315 *addr++ = 0; 316 317 /* 318 * Load DATA Segment 319 */ 320 321 printf("+%d", header.a_data); 322 if (tread(/*io,*/ addr, header.a_data) != header.a_data) 323 goto shread; 324 325 /* 326 * Clear BSS Segment 327 */ 328 329 addr += header.a_data; 330 printf("+%d", header.a_bss); 331 header.a_bss += 128*512; /* slop */ 332 for (i = 0; i < header.a_bss; i++) 333 *addr++ = 0; 334 335 return(load); 336 337 shread: 338 printf(" Short read\n"); 339 return(0); 340 } 341 342 int 343 tread(addr, size) 344 int addr; 345 int size; 346 { 347 static u_char buf[512]; 348 static int head = 512; 349 static int tail = 512; 350 int req_size = size; 351 int rest = tail - head; 352 353 if (rest > 0) { 354 if (size <= rest) { 355 bcopy(&buf[head], addr, size); 356 head += size; 357 return size; 358 } else { /* size > rest */ 359 bcopy(&buf[head], addr, rest); 360 addr += rest; 361 size -= rest; 362 if (tail != 512) { 363 head = 512; 364 tail = 512; 365 printf("tread() EOF 0\n"); 366 return rest; 367 } 368 } 369 } 370 371 /* head = 0; */ 372 373 while (size > 512) { 374 if ((tail = stread(rst0, addr, 512)) == 512) { 375 addr += 512; 376 size -= 512; 377 } else { /* eof ( tail < 512 ) */ 378 size -= tail; 379 head = tail; 380 printf("tread() EOF 1\n"); 381 return req_size - size; 382 } 383 } 384 tail = stread(rst0, buf, 512); 385 if (tail >= size) { 386 bcopy(buf, addr, size); 387 head = size; 388 return req_size; 389 } else { 390 bcopy(buf, addr, tail); 391 head = tail; 392 printf("tread() EOF 2\n"); 393 return req_size - size; 394 } 395 } 396 397 #endif 398 399