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*57518Sakito * @(#)boot.c 7.2 (Berkeley) 01/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; 29*57518Sakito 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 4757081Sakito int 4857081Sakito how_to_boot(argc, argv) 4957081Sakito int argc; 5057081Sakito char *argv[]; 5157081Sakito { 5257081Sakito int i, h = howto; 5357081Sakito 5457081Sakito if (argc < 2) { 5557081Sakito printf("howto: 0x%s\n\n", hexstr(howto, 2)); 5657081Sakito 5757081Sakito if (h == 0) { 5857081Sakito printf("\t%s\n", "RB_AUTOBOOT flags for system auto-booting itself"); 5957081Sakito } else { 6057081Sakito for (i = 0; i < 8; i++, h >>= 1) { 6157081Sakito if (h & 0x01) { 6257081Sakito printf("\t%s\n", how_to_info[i]); 6357081Sakito } 6457081Sakito } 6557081Sakito } 6657081Sakito 6757081Sakito printf("\n"); 6857081Sakito } 6957081Sakito } 7057081Sakito 7157081Sakito int 72*57518Sakito get_boot_device(s) 73*57518Sakito char *s; 74*57518Sakito { 75*57518Sakito register int unit = 0; 76*57518Sakito register int part = 0; 77*57518Sakito register char *p = s; 78*57518Sakito 79*57518Sakito while (*p != '(') { 80*57518Sakito if (*p == '\0') 81*57518Sakito goto error; 82*57518Sakito p++; 83*57518Sakito } 84*57518Sakito 85*57518Sakito while (*++p != ',') { 86*57518Sakito if (*p == '\0') 87*57518Sakito goto error; 88*57518Sakito if (*p >= '0' && *p <= '9') 89*57518Sakito unit = (unit * 10) + (*p - '0'); 90*57518Sakito } 91*57518Sakito 92*57518Sakito while (*++p != ')') { 93*57518Sakito if (*p == '\0') 94*57518Sakito goto error; 95*57518Sakito if (*p >= '0' && *p <= '9') 96*57518Sakito part = (part * 10) + (*p - '0'); 97*57518Sakito } 98*57518Sakito 99*57518Sakito return(MAKEBOOTDEV(4, 0, (6 - unit), unit, part)); 100*57518Sakito 101*57518Sakito error: 102*57518Sakito return(MAKEBOOTDEV(4, 0, 6, 0, 0)); 103*57518Sakito } 104*57518Sakito 105*57518Sakito int 10657081Sakito boot(argc, argv) 10757081Sakito int argc; 10857081Sakito char *argv[]; 10957081Sakito { 11057081Sakito register int io; 11157081Sakito char *line; 11257081Sakito 11357081Sakito if (argc < 2) 11457081Sakito line = default_file; 11557081Sakito else 11657081Sakito line = argv[1]; 11757081Sakito 118*57518Sakito devtype = get_boot_device(line); 119*57518Sakito 12057081Sakito printf("Booting %s\n", line); 12157081Sakito 12257081Sakito io = open(line, 0); 12357081Sakito if (io >= 0) { 12457081Sakito bootunix(howto, devtype, io); 12557081Sakito close(io); 12657081Sakito } 12757081Sakito } 12857081Sakito 12957081Sakito int 13057081Sakito load(argc, argv) 13157081Sakito int argc; 13257081Sakito char *argv[]; 13357081Sakito { 13457081Sakito register int io; 13557081Sakito char *line; 13657081Sakito 13757081Sakito if (argc < 2) 13857081Sakito line = default_file; 13957081Sakito else 14057081Sakito line = argv[1]; 14157081Sakito 14257081Sakito printf("loading %s\n", line); 14357081Sakito 14457081Sakito io = open(line, 0); 14557081Sakito if (io >= 0) { 14657081Sakito copyunix(io); 14757081Sakito printf("\n"); 14857081Sakito close(io); 14957081Sakito } 15057081Sakito } 15157081Sakito 15257081Sakito int 15357081Sakito bootunix(howto, devtype, io) 15457081Sakito register howto; /* d7 contains boot flags */ 15557081Sakito register devtype; /* d6 contains boot device */ 15657081Sakito register io; 15757081Sakito { 15857081Sakito register char *load; /* a5 contains load addr for unix */ 15957081Sakito 16057081Sakito load = copyunix(io); 16157081Sakito 16257081Sakito printf(" start 0x%x\n", load); 16357081Sakito asm(" movl %0,d7" : : "d" (howto)); 16457081Sakito asm(" movl %0,d6" : : "d" (devtype)); 16557081Sakito asm(" movl %0,a5" : : "a" (kiff)); 16657081Sakito (*((int (*)()) load))(); 16757081Sakito } 16857081Sakito 16957081Sakito char * 17057081Sakito copyunix(io) 17157081Sakito register io; 17257081Sakito { 17357081Sakito 17457081Sakito register int i; 17557081Sakito register char *load; /* a5 contains load addr for unix */ 17657081Sakito register char *addr; 17757081Sakito 17857081Sakito /* 17957081Sakito * Read a.out file header 18057081Sakito */ 18157081Sakito 18257081Sakito i = read(io, (char *)&header, sizeof(struct exec)); 18357081Sakito if (i != sizeof(struct exec) || 18457081Sakito (header.a_magic != 0407 && header.a_magic != 0413 && header.a_magic != 0410)) { 18557081Sakito printf("illegal magic number ... 0x%x\n"); 18657081Sakito printf("Bad format\n"); 18757081Sakito return(0); 18857081Sakito } 18957081Sakito 19057081Sakito load = addr = (char *) (header.a_entry & 0x00FFFFFF); 19157081Sakito 19257081Sakito printf("%d", header.a_text); 19357081Sakito if (header.a_magic == 0413 && lseek(io, 0x400, 0) == -1) 19457081Sakito goto shread; 19557081Sakito 19657081Sakito /* 19757081Sakito * Load TEXT Segment 19857081Sakito */ 19957081Sakito 20057081Sakito if (read(io, (char *)addr, header.a_text) != header.a_text) 20157081Sakito goto shread; 20257081Sakito addr += header.a_text; 20357081Sakito if (header.a_magic == 0413 || header.a_magic == 0410) 20457081Sakito while ((int)addr & CLOFSET) 20557081Sakito *addr++ = 0; 20657081Sakito 20757081Sakito /* 20857081Sakito * Load DATA Segment 20957081Sakito */ 21057081Sakito 21157081Sakito printf("+%d", header.a_data); 21257081Sakito if (read(io, addr, header.a_data) != header.a_data) 21357081Sakito goto shread; 21457081Sakito 21557081Sakito /* 21657081Sakito * Clear BSS Segment 21757081Sakito */ 21857081Sakito 21957081Sakito addr += header.a_data; 22057081Sakito printf("+%d", header.a_bss); 22157081Sakito header.a_bss += 128*512; /* slop */ 22257081Sakito for (i = 0; i < header.a_bss; i++) 22357081Sakito *addr++ = 0; 22457081Sakito 22557081Sakito return(load); 22657081Sakito 22757081Sakito shread: 22857081Sakito printf(" Short read\n"); 22957081Sakito return(0); 23057081Sakito } 23157081Sakito 232