157081Sakito /* 257081Sakito * Copyright (c) 1992 OMRON Corporation. 357081Sakito * Copyright (c) 1992 The Regents of the University of California. 457081Sakito * All rights reserved. 557081Sakito * 657081Sakito * This code is derived from software contributed to Berkeley by 757081Sakito * OMRON Corporation. 857081Sakito * 957081Sakito * %sccs.include.redist.c% 1057081Sakito * 11*59955Sakito * @(#)boot.c 7.3 (Berkeley) 05/12/93 1257081Sakito */ 1357081Sakito 1457081Sakito /* 1557081Sakito * boot.c -- boot program 1657081Sakito * by A.Fujita, MAR-01-1992 1757081Sakito */ 1857081Sakito 1957081Sakito #include <sys/param.h> 2057081Sakito #include <sys/reboot.h> 2157081Sakito #include <sys/exec.h> 2257081Sakito #include <machine/stinger.h> 2357081Sakito #include <luna68k/stand/saio.h> 2457081Sakito #include <luna68k/stand/status.h> 2557081Sakito 2657081Sakito extern struct KernInter *kiff; 2757081Sakito 2857081Sakito int howto; 2957518Sakito int devtype = MAKEBOOTDEV(4, 0, 6, 0, 0); 3057081Sakito 3157081Sakito char *copyunix(); 3257081Sakito 3357081Sakito struct exec header; 3457081Sakito char default_file[] = "sd(0,0)vmunix"; 3557081Sakito 3657081Sakito char *how_to_info[] = { 3757081Sakito "RB_ASKNAME ask for file name to reboot from", 3857081Sakito "RB_SINGLE reboot to single user only", 3957081Sakito "RB_NOSYNC dont sync before reboot", 4057081Sakito "RB_HALT don't reboot, just halt", 4157081Sakito "RB_INITNAME name given for /etc/init (unused)", 4257081Sakito "RB_DFLTROOT use compiled-in rootdev", 4357081Sakito "RB_KDB give control to kernel debugger", 4457081Sakito "RB_RDONLY mount root fs read-only" 4557081Sakito }; 4657081Sakito 47*59955Sakito #define TAPE 48*59955Sakito #ifdef TAPE /* A.Kojima */ 49*59955Sakito extern dev_t rst0; 50*59955Sakito extern dev_t nrst0; 51*59955Sakito char *stcopyunix(); 52*59955Sakito #endif 53*59955Sakito 5457081Sakito int 5557081Sakito how_to_boot(argc, argv) 5657081Sakito int argc; 5757081Sakito char *argv[]; 5857081Sakito { 5957081Sakito int i, h = howto; 6057081Sakito 6157081Sakito if (argc < 2) { 6257081Sakito printf("howto: 0x%s\n\n", hexstr(howto, 2)); 6357081Sakito 6457081Sakito if (h == 0) { 6557081Sakito printf("\t%s\n", "RB_AUTOBOOT flags for system auto-booting itself"); 6657081Sakito } else { 6757081Sakito for (i = 0; i < 8; i++, h >>= 1) { 6857081Sakito if (h & 0x01) { 6957081Sakito printf("\t%s\n", how_to_info[i]); 7057081Sakito } 7157081Sakito } 7257081Sakito } 7357081Sakito 7457081Sakito printf("\n"); 7557081Sakito } 7657081Sakito } 7757081Sakito 7857081Sakito int 7957518Sakito get_boot_device(s) 8057518Sakito char *s; 8157518Sakito { 8257518Sakito register int unit = 0; 8357518Sakito register int part = 0; 8457518Sakito register char *p = s; 8557518Sakito 8657518Sakito while (*p != '(') { 8757518Sakito if (*p == '\0') 8857518Sakito goto error; 8957518Sakito p++; 9057518Sakito } 9157518Sakito 9257518Sakito while (*++p != ',') { 9357518Sakito if (*p == '\0') 9457518Sakito goto error; 9557518Sakito if (*p >= '0' && *p <= '9') 9657518Sakito unit = (unit * 10) + (*p - '0'); 9757518Sakito } 9857518Sakito 9957518Sakito while (*++p != ')') { 10057518Sakito if (*p == '\0') 10157518Sakito goto error; 10257518Sakito if (*p >= '0' && *p <= '9') 10357518Sakito part = (part * 10) + (*p - '0'); 10457518Sakito } 10557518Sakito 10657518Sakito return(MAKEBOOTDEV(4, 0, (6 - unit), unit, part)); 10757518Sakito 10857518Sakito error: 10957518Sakito return(MAKEBOOTDEV(4, 0, 6, 0, 0)); 11057518Sakito } 11157518Sakito 11257518Sakito int 11357081Sakito boot(argc, argv) 11457081Sakito int argc; 11557081Sakito char *argv[]; 11657081Sakito { 11757081Sakito register int io; 11857081Sakito char *line; 11957081Sakito 12057081Sakito if (argc < 2) 12157081Sakito line = default_file; 12257081Sakito else 12357081Sakito line = argv[1]; 12457081Sakito 12557518Sakito devtype = get_boot_device(line); 12657518Sakito 12757081Sakito printf("Booting %s\n", line); 12857081Sakito 129*59955Sakito #ifdef TAPE /* A.Kojima */ 130*59955Sakito if (!strcmp("st", argv[1])) { 131*59955Sakito io = argc < 3 ? 0 : *argv[2] - '0'; 132*59955Sakito printf("boot tape file number:%d\n", io); 133*59955Sakito stbootunix(howto, devtype, io); 134*59955Sakito return; 135*59955Sakito } 136*59955Sakito #endif 13757081Sakito io = open(line, 0); 13857081Sakito if (io >= 0) { 13957081Sakito bootunix(howto, devtype, io); 14057081Sakito close(io); 14157081Sakito } 14257081Sakito } 14357081Sakito 14457081Sakito int 14557081Sakito load(argc, argv) 14657081Sakito int argc; 14757081Sakito char *argv[]; 14857081Sakito { 14957081Sakito register int io; 15057081Sakito char *line; 15157081Sakito 15257081Sakito if (argc < 2) 15357081Sakito line = default_file; 15457081Sakito else 15557081Sakito line = argv[1]; 15657081Sakito 15757081Sakito printf("loading %s\n", line); 15857081Sakito 15957081Sakito io = open(line, 0); 16057081Sakito if (io >= 0) { 16157081Sakito copyunix(io); 16257081Sakito printf("\n"); 16357081Sakito close(io); 16457081Sakito } 16557081Sakito } 16657081Sakito 16757081Sakito int 16857081Sakito bootunix(howto, devtype, io) 16957081Sakito register howto; /* d7 contains boot flags */ 17057081Sakito register devtype; /* d6 contains boot device */ 17157081Sakito register io; 17257081Sakito { 17357081Sakito register char *load; /* a5 contains load addr for unix */ 17457081Sakito 17557081Sakito load = copyunix(io); 17657081Sakito 17757081Sakito printf(" start 0x%x\n", load); 17857081Sakito asm(" movl %0,d7" : : "d" (howto)); 17957081Sakito asm(" movl %0,d6" : : "d" (devtype)); 18057081Sakito asm(" movl %0,a5" : : "a" (kiff)); 18157081Sakito (*((int (*)()) load))(); 18257081Sakito } 18357081Sakito 18457081Sakito char * 18557081Sakito copyunix(io) 18657081Sakito register io; 18757081Sakito { 18857081Sakito 18957081Sakito register int i; 19057081Sakito register char *load; /* a5 contains load addr for unix */ 19157081Sakito register char *addr; 19257081Sakito 19357081Sakito /* 19457081Sakito * Read a.out file header 19557081Sakito */ 19657081Sakito 19757081Sakito i = read(io, (char *)&header, sizeof(struct exec)); 19857081Sakito if (i != sizeof(struct exec) || 19957081Sakito (header.a_magic != 0407 && header.a_magic != 0413 && header.a_magic != 0410)) { 20057081Sakito printf("illegal magic number ... 0x%x\n"); 20157081Sakito printf("Bad format\n"); 20257081Sakito return(0); 20357081Sakito } 20457081Sakito 20557081Sakito load = addr = (char *) (header.a_entry & 0x00FFFFFF); 20657081Sakito 20757081Sakito printf("%d", header.a_text); 20857081Sakito if (header.a_magic == 0413 && lseek(io, 0x400, 0) == -1) 20957081Sakito goto shread; 21057081Sakito 21157081Sakito /* 21257081Sakito * Load TEXT Segment 21357081Sakito */ 21457081Sakito 21557081Sakito if (read(io, (char *)addr, header.a_text) != header.a_text) 21657081Sakito goto shread; 21757081Sakito addr += header.a_text; 21857081Sakito if (header.a_magic == 0413 || header.a_magic == 0410) 21957081Sakito while ((int)addr & CLOFSET) 22057081Sakito *addr++ = 0; 22157081Sakito 22257081Sakito /* 22357081Sakito * Load DATA Segment 22457081Sakito */ 22557081Sakito 22657081Sakito printf("+%d", header.a_data); 22757081Sakito if (read(io, addr, header.a_data) != header.a_data) 22857081Sakito goto shread; 22957081Sakito 23057081Sakito /* 23157081Sakito * Clear BSS Segment 23257081Sakito */ 23357081Sakito 23457081Sakito addr += header.a_data; 23557081Sakito printf("+%d", header.a_bss); 23657081Sakito header.a_bss += 128*512; /* slop */ 23757081Sakito for (i = 0; i < header.a_bss; i++) 23857081Sakito *addr++ = 0; 23957081Sakito 24057081Sakito return(load); 24157081Sakito 24257081Sakito shread: 24357081Sakito printf(" Short read\n"); 24457081Sakito return(0); 24557081Sakito } 24657081Sakito 247*59955Sakito #ifdef TAPE /* A.Kojima */ 248*59955Sakito int 249*59955Sakito stbootunix(howto, devtype, skip) 250*59955Sakito register howto; /* d7 contains boot flags */ 251*59955Sakito register devtype; /* d6 contains boot device */ 252*59955Sakito register skip; /* tape skip */ 253*59955Sakito { 254*59955Sakito register int i; 255*59955Sakito register char *load; /* a5 contains load addr for unix */ 256*59955Sakito 257*59955Sakito /* 258*59955Sakito * Tape rewind and skip 259*59955Sakito */ 260*59955Sakito st_rewind(rst0); 261*59955Sakito for (i = 0; i < skip; i++) { 262*59955Sakito st_skip(rst0); 263*59955Sakito } 264*59955Sakito 265*59955Sakito load = stcopyunix(); 266*59955Sakito 267*59955Sakito st_rewind(rst0); 268*59955Sakito 269*59955Sakito printf(" start 0x%x\n", load); 270*59955Sakito asm(" movl %0,d7" : : "d" (howto)); 271*59955Sakito asm(" movl %0,d6" : : "d" (devtype)); 272*59955Sakito asm(" movl %0,a5" : : "a" (kiff)); 273*59955Sakito (*((int (*)()) load))(); 274*59955Sakito } 275*59955Sakito 276*59955Sakito char * 277*59955Sakito stcopyunix() 278*59955Sakito { 279*59955Sakito 280*59955Sakito register int i; 281*59955Sakito register char *load; /* a5 contains load addr for unix */ 282*59955Sakito register char *addr; 283*59955Sakito u_char buf[0x400]; 284*59955Sakito 285*59955Sakito /* 286*59955Sakito * Read a.out file header 287*59955Sakito */ 288*59955Sakito 289*59955Sakito i = tread(/*io,*/ (char *)&header, sizeof(struct exec)); 290*59955Sakito if (i != sizeof(struct exec) || 291*59955Sakito (header.a_magic != 0407 && header.a_magic != 0413 && header.a_magic != 0410)) { 292*59955Sakito printf("illegal magic number ... 0x%x\n"); 293*59955Sakito printf("Bad format\n"); 294*59955Sakito return(0); 295*59955Sakito } 296*59955Sakito 297*59955Sakito load = addr = (char *) (header.a_entry & 0x00FFFFFF); 298*59955Sakito 299*59955Sakito printf("%d", header.a_text); 300*59955Sakito 301*59955Sakito i = 0x400 - i; 302*59955Sakito if (header.a_magic == 0413 && tread(buf, i) != i) { /* easy seek */ 303*59955Sakito goto shread; 304*59955Sakito } 305*59955Sakito 306*59955Sakito /* 307*59955Sakito * Load TEXT Segment 308*59955Sakito */ 309*59955Sakito 310*59955Sakito if (tread(/*io,*/ (char *)addr, header.a_text) != header.a_text) 311*59955Sakito goto shread; 312*59955Sakito addr += header.a_text; 313*59955Sakito if (header.a_magic == 0413 || header.a_magic == 0410) 314*59955Sakito while ((int)addr & CLOFSET) 315*59955Sakito *addr++ = 0; 316*59955Sakito 317*59955Sakito /* 318*59955Sakito * Load DATA Segment 319*59955Sakito */ 320*59955Sakito 321*59955Sakito printf("+%d", header.a_data); 322*59955Sakito if (tread(/*io,*/ addr, header.a_data) != header.a_data) 323*59955Sakito goto shread; 324*59955Sakito 325*59955Sakito /* 326*59955Sakito * Clear BSS Segment 327*59955Sakito */ 328*59955Sakito 329*59955Sakito addr += header.a_data; 330*59955Sakito printf("+%d", header.a_bss); 331*59955Sakito header.a_bss += 128*512; /* slop */ 332*59955Sakito for (i = 0; i < header.a_bss; i++) 333*59955Sakito *addr++ = 0; 334*59955Sakito 335*59955Sakito return(load); 336*59955Sakito 337*59955Sakito shread: 338*59955Sakito printf(" Short read\n"); 339*59955Sakito return(0); 340*59955Sakito } 341*59955Sakito 342*59955Sakito int 343*59955Sakito tread(addr, size) 344*59955Sakito int addr; 345*59955Sakito int size; 346*59955Sakito { 347*59955Sakito static u_char buf[512]; 348*59955Sakito static int head = 512; 349*59955Sakito static int tail = 512; 350*59955Sakito int req_size = size; 351*59955Sakito int rest = tail - head; 352*59955Sakito 353*59955Sakito if (rest > 0) { 354*59955Sakito if (size <= rest) { 355*59955Sakito bcopy(&buf[head], addr, size); 356*59955Sakito head += size; 357*59955Sakito return size; 358*59955Sakito } else { /* size > rest */ 359*59955Sakito bcopy(&buf[head], addr, rest); 360*59955Sakito addr += rest; 361*59955Sakito size -= rest; 362*59955Sakito if (tail != 512) { 363*59955Sakito head = 512; 364*59955Sakito tail = 512; 365*59955Sakito printf("tread() EOF 0\n"); 366*59955Sakito return rest; 367*59955Sakito } 368*59955Sakito } 369*59955Sakito } 370*59955Sakito 371*59955Sakito /* head = 0; */ 372*59955Sakito 373*59955Sakito while (size > 512) { 374*59955Sakito if ((tail = stread(rst0, addr, 512)) == 512) { 375*59955Sakito addr += 512; 376*59955Sakito size -= 512; 377*59955Sakito } else { /* eof ( tail < 512 ) */ 378*59955Sakito size -= tail; 379*59955Sakito head = tail; 380*59955Sakito printf("tread() EOF 1\n"); 381*59955Sakito return req_size - size; 382*59955Sakito } 383*59955Sakito } 384*59955Sakito tail = stread(rst0, buf, 512); 385*59955Sakito if (tail >= size) { 386*59955Sakito bcopy(buf, addr, size); 387*59955Sakito head = size; 388*59955Sakito return req_size; 389*59955Sakito } else { 390*59955Sakito bcopy(buf, addr, tail); 391*59955Sakito head = tail; 392*59955Sakito printf("tread() EOF 2\n"); 393*59955Sakito return req_size - size; 394*59955Sakito } 395*59955Sakito } 396*59955Sakito 397*59955Sakito #endif 398*59955Sakito 399