1*41488Smckusick /* 2*41488Smckusick * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. 3*41488Smckusick * All rights reserved. 4*41488Smckusick * 5*41488Smckusick * %sccs.include.redist.c% 6*41488Smckusick * 7*41488Smckusick * @(#)boot.c 7.1 (Berkeley) 05/08/90 8*41488Smckusick */ 9*41488Smckusick 10*41488Smckusick #include <a.out.h> 11*41488Smckusick #include "saio.h" 12*41488Smckusick #include "../sys/reboot.h" 13*41488Smckusick 14*41488Smckusick #ifndef INSECURE 15*41488Smckusick #include "../sys/stat.h" 16*41488Smckusick struct stat sb; 17*41488Smckusick #endif 18*41488Smckusick 19*41488Smckusick #define B_MAKEDEV(a,u,p,t) \ 20*41488Smckusick (((a) << B_ADAPTORSHIFT) | ((u) << B_UNITSHIFT) | \ 21*41488Smckusick ((p) << B_PARTITIONSHIFT) | ((t) << B_TYPESHIFT)) 22*41488Smckusick 23*41488Smckusick /* 24*41488Smckusick * Boot program... arguments in `devtype' and `howto' determine 25*41488Smckusick * whether boot stops to ask for system name and which device 26*41488Smckusick * boot comes from. 27*41488Smckusick */ 28*41488Smckusick 29*41488Smckusick /* Types in `devtype' specifying major device */ 30*41488Smckusick char devname[][2] = { 31*41488Smckusick 0,0, /* 0 = ct */ 32*41488Smckusick 0,0, /* 1 = fd */ 33*41488Smckusick 'r','d', /* 2 = rd */ 34*41488Smckusick 0,0, /* 3 = sw */ 35*41488Smckusick 's','d', /* 4 = sd */ 36*41488Smckusick }; 37*41488Smckusick #define MAXTYPE (sizeof(devname) / sizeof(devname[0])) 38*41488Smckusick 39*41488Smckusick #define UNIX "vmunix" 40*41488Smckusick char line[100]; 41*41488Smckusick 42*41488Smckusick int retry = 0; 43*41488Smckusick extern char *lowram; 44*41488Smckusick extern int noconsole; 45*41488Smckusick extern int howto, devtype; 46*41488Smckusick 47*41488Smckusick #define MSUS (0xfffffedc) 48*41488Smckusick 49*41488Smckusick char rom2mdev[] = { 50*41488Smckusick 0, /* 0 - none */ 51*41488Smckusick 0, /* 1 - none */ 52*41488Smckusick 0, /* 2 - none */ 53*41488Smckusick 0, /* 3 - none */ 54*41488Smckusick 0, /* 4 - none */ 55*41488Smckusick 0, /* 5 - none */ 56*41488Smckusick 0, /* 6 - none */ 57*41488Smckusick 0, /* 7 - none */ 58*41488Smckusick 0, /* 8 - none */ 59*41488Smckusick 0, /* 9 - none */ 60*41488Smckusick 0, /* 10 - none */ 61*41488Smckusick 0, /* 11 - none */ 62*41488Smckusick 0, /* 12 - none */ 63*41488Smckusick 0, /* 13 - none */ 64*41488Smckusick 4, /* 14 - SCSI disk */ 65*41488Smckusick 0, /* 15 - none */ 66*41488Smckusick 2, /* 16 - CS/80 device on HPIB */ 67*41488Smckusick 2, /* 17 - CS/80 device on HPIB */ 68*41488Smckusick 0, /* 18 - none */ 69*41488Smckusick 0, /* 19 - none */ 70*41488Smckusick 0, /* 20 - none */ 71*41488Smckusick 0, /* 21 - none */ 72*41488Smckusick 0, /* 22 - none */ 73*41488Smckusick 0, /* 23 - none */ 74*41488Smckusick 0, /* 24 - none */ 75*41488Smckusick 0, /* 25 - none */ 76*41488Smckusick 0, /* 26 - none */ 77*41488Smckusick 0, /* 27 - none */ 78*41488Smckusick 0, /* 28 - none */ 79*41488Smckusick 0, /* 29 - none */ 80*41488Smckusick 0, /* 30 - none */ 81*41488Smckusick 0, /* 31 - none */ 82*41488Smckusick }; 83*41488Smckusick 84*41488Smckusick main() 85*41488Smckusick { 86*41488Smckusick register type, part, unit, io; 87*41488Smckusick register char *cp; 88*41488Smckusick 89*41488Smckusick printf("\nBoot\n"); 90*41488Smckusick #ifdef JUSTASK 91*41488Smckusick howto = RB_ASKNAME|RB_SINGLE; 92*41488Smckusick #else 93*41488Smckusick type = (devtype >> B_TYPESHIFT) & B_TYPEMASK; 94*41488Smckusick unit = (devtype >> B_UNITSHIFT) & B_UNITMASK; 95*41488Smckusick unit += 8 * ((devtype >> B_ADAPTORSHIFT) & B_ADAPTORMASK); 96*41488Smckusick part = (devtype >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 97*41488Smckusick if ((howto & RB_ASKNAME) == 0) { 98*41488Smckusick if ((devtype & B_MAGICMASK) != B_DEVMAGIC) { 99*41488Smckusick /* 100*41488Smckusick * we have to map the ROM device type codes 101*41488Smckusick * to Unix major device numbers. 102*41488Smckusick */ 103*41488Smckusick type = rom2mdev[*(char *)MSUS & 0x1f]; 104*41488Smckusick devtype = (devtype &~ (B_TYPEMASK << B_TYPESHIFT)) 105*41488Smckusick | (type << B_TYPESHIFT); 106*41488Smckusick } 107*41488Smckusick if (type >= 0 && type <= MAXTYPE && devname[type][0]) { 108*41488Smckusick cp = line; 109*41488Smckusick *cp++ = devname[type][0]; 110*41488Smckusick *cp++ = devname[type][1]; 111*41488Smckusick *cp++ = '('; 112*41488Smckusick if (unit >= 10) 113*41488Smckusick *cp++ = unit / 10 + '0'; 114*41488Smckusick *cp++ = unit % 10 + '0'; 115*41488Smckusick *cp++ = ','; 116*41488Smckusick *cp++ = part + '0'; 117*41488Smckusick *cp++ = ')'; 118*41488Smckusick strcpy(cp, UNIX); 119*41488Smckusick } else 120*41488Smckusick howto = RB_SINGLE|RB_ASKNAME; 121*41488Smckusick } 122*41488Smckusick #endif 123*41488Smckusick for (;;) { 124*41488Smckusick if (!noconsole && (howto & RB_ASKNAME)) { 125*41488Smckusick printf(": "); 126*41488Smckusick gets(line); 127*41488Smckusick } else 128*41488Smckusick printf(": %s\n", line); 129*41488Smckusick io = open(line, 0); 130*41488Smckusick if (io >= 0) { 131*41488Smckusick #ifndef INSECURE 132*41488Smckusick (void) fstat(io, &sb); 133*41488Smckusick if (sb.st_uid || (sb.st_mode & 2)) { 134*41488Smckusick printf("non-secure file, will not load\n"); 135*41488Smckusick howto = RB_SINGLE|RB_ASKNAME; 136*41488Smckusick continue; 137*41488Smckusick } 138*41488Smckusick #endif 139*41488Smckusick if (howto & RB_ASKNAME) { 140*41488Smckusick /* 141*41488Smckusick * Build up devtype register to pass on to 142*41488Smckusick * booted program. 143*41488Smckusick */ 144*41488Smckusick cp = line; 145*41488Smckusick for (type = 0; type <= MAXTYPE; type++) 146*41488Smckusick if ((devname[type][0] == cp[0]) && 147*41488Smckusick (devname[type][1] == cp[1])) 148*41488Smckusick break; 149*41488Smckusick if (type <= MAXTYPE) { 150*41488Smckusick cp += 3; 151*41488Smckusick unit = *cp++ - '0'; 152*41488Smckusick if (*cp >= '0' && *cp <= '9') 153*41488Smckusick unit = unit * 10 + *cp++ - '0'; 154*41488Smckusick cp++; 155*41488Smckusick part = atol(cp); 156*41488Smckusick devtype = B_MAKEDEV(unit >> 3, unit & 7, part, type); 157*41488Smckusick } 158*41488Smckusick } 159*41488Smckusick devtype |= B_DEVMAGIC; 160*41488Smckusick copyunix(howto, devtype, io); 161*41488Smckusick close(io); 162*41488Smckusick howto = RB_SINGLE|RB_ASKNAME; 163*41488Smckusick } 164*41488Smckusick bad: 165*41488Smckusick if (++retry > 2) 166*41488Smckusick howto = RB_SINGLE|RB_ASKNAME; 167*41488Smckusick } 168*41488Smckusick } 169*41488Smckusick 170*41488Smckusick /*ARGSUSED*/ 171*41488Smckusick copyunix(howto, devtype, io) 172*41488Smckusick register howto; /* d7 contains boot flags */ 173*41488Smckusick register devtype; /* d6 contains boot device */ 174*41488Smckusick register io; 175*41488Smckusick { 176*41488Smckusick struct exec x; 177*41488Smckusick register int i; 178*41488Smckusick register char *load; /* a5 contains load addr for unix */ 179*41488Smckusick register char *addr; 180*41488Smckusick 181*41488Smckusick i = read(io, (char *)&x, sizeof x); 182*41488Smckusick if (i != sizeof x || 183*41488Smckusick (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410)) 184*41488Smckusick _stop("Bad format\n"); 185*41488Smckusick printf("%d", x.a_text); 186*41488Smckusick if (x.a_magic == 0413 && lseek(io, 0x400, 0) == -1) 187*41488Smckusick goto shread; 188*41488Smckusick load = addr = lowram; 189*41488Smckusick if (read(io, (char *)addr, x.a_text) != x.a_text) 190*41488Smckusick goto shread; 191*41488Smckusick addr += x.a_text; 192*41488Smckusick if (x.a_magic == 0413 || x.a_magic == 0410) 193*41488Smckusick while ((int)addr & CLOFSET) 194*41488Smckusick *addr++ = 0; 195*41488Smckusick printf("+%d", x.a_data); 196*41488Smckusick if (read(io, addr, x.a_data) != x.a_data) 197*41488Smckusick goto shread; 198*41488Smckusick addr += x.a_data; 199*41488Smckusick printf("+%d", x.a_bss); 200*41488Smckusick x.a_bss += 128*512; /* slop */ 201*41488Smckusick for (i = 0; i < x.a_bss; i++) 202*41488Smckusick *addr++ = 0; 203*41488Smckusick x.a_entry += (int)lowram; 204*41488Smckusick printf(" start 0x%x\n", x.a_entry); 205*41488Smckusick #ifdef __GNUC__ 206*41488Smckusick asm(" movl %0,d7" : : "m" (howto)); 207*41488Smckusick asm(" movl %0,d6" : : "m" (devtype)); 208*41488Smckusick asm(" movl %0,a5" : : "a" (load)); 209*41488Smckusick #endif 210*41488Smckusick (*((int (*)()) x.a_entry))(); 211*41488Smckusick exit(); 212*41488Smckusick shread: 213*41488Smckusick _stop("Short read\n"); 214*41488Smckusick } 215