141488Smckusick /* 241488Smckusick * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. 341488Smckusick * All rights reserved. 441488Smckusick * 541488Smckusick * %sccs.include.redist.c% 641488Smckusick * 7*45790Sbostic * @(#)boot.c 7.2 (Berkeley) 12/16/90 841488Smckusick */ 941488Smckusick 1041488Smckusick #include <a.out.h> 1141488Smckusick #include "saio.h" 12*45790Sbostic #include "sys/reboot.h" 1341488Smckusick 1441488Smckusick #ifndef INSECURE 15*45790Sbostic #include "sys/stat.h" 1641488Smckusick struct stat sb; 1741488Smckusick #endif 1841488Smckusick 1941488Smckusick #define B_MAKEDEV(a,u,p,t) \ 2041488Smckusick (((a) << B_ADAPTORSHIFT) | ((u) << B_UNITSHIFT) | \ 2141488Smckusick ((p) << B_PARTITIONSHIFT) | ((t) << B_TYPESHIFT)) 2241488Smckusick 2341488Smckusick /* 2441488Smckusick * Boot program... arguments in `devtype' and `howto' determine 2541488Smckusick * whether boot stops to ask for system name and which device 2641488Smckusick * boot comes from. 2741488Smckusick */ 2841488Smckusick 2941488Smckusick /* Types in `devtype' specifying major device */ 3041488Smckusick char devname[][2] = { 3141488Smckusick 0,0, /* 0 = ct */ 3241488Smckusick 0,0, /* 1 = fd */ 3341488Smckusick 'r','d', /* 2 = rd */ 3441488Smckusick 0,0, /* 3 = sw */ 3541488Smckusick 's','d', /* 4 = sd */ 3641488Smckusick }; 3741488Smckusick #define MAXTYPE (sizeof(devname) / sizeof(devname[0])) 3841488Smckusick 3941488Smckusick #define UNIX "vmunix" 4041488Smckusick char line[100]; 4141488Smckusick 4241488Smckusick int retry = 0; 4341488Smckusick extern char *lowram; 4441488Smckusick extern int noconsole; 4541488Smckusick extern int howto, devtype; 4641488Smckusick 4741488Smckusick #define MSUS (0xfffffedc) 4841488Smckusick 4941488Smckusick char rom2mdev[] = { 5041488Smckusick 0, /* 0 - none */ 5141488Smckusick 0, /* 1 - none */ 5241488Smckusick 0, /* 2 - none */ 5341488Smckusick 0, /* 3 - none */ 5441488Smckusick 0, /* 4 - none */ 5541488Smckusick 0, /* 5 - none */ 5641488Smckusick 0, /* 6 - none */ 5741488Smckusick 0, /* 7 - none */ 5841488Smckusick 0, /* 8 - none */ 5941488Smckusick 0, /* 9 - none */ 6041488Smckusick 0, /* 10 - none */ 6141488Smckusick 0, /* 11 - none */ 6241488Smckusick 0, /* 12 - none */ 6341488Smckusick 0, /* 13 - none */ 6441488Smckusick 4, /* 14 - SCSI disk */ 6541488Smckusick 0, /* 15 - none */ 6641488Smckusick 2, /* 16 - CS/80 device on HPIB */ 6741488Smckusick 2, /* 17 - CS/80 device on HPIB */ 6841488Smckusick 0, /* 18 - none */ 6941488Smckusick 0, /* 19 - none */ 7041488Smckusick 0, /* 20 - none */ 7141488Smckusick 0, /* 21 - none */ 7241488Smckusick 0, /* 22 - none */ 7341488Smckusick 0, /* 23 - none */ 7441488Smckusick 0, /* 24 - none */ 7541488Smckusick 0, /* 25 - none */ 7641488Smckusick 0, /* 26 - none */ 7741488Smckusick 0, /* 27 - none */ 7841488Smckusick 0, /* 28 - none */ 7941488Smckusick 0, /* 29 - none */ 8041488Smckusick 0, /* 30 - none */ 8141488Smckusick 0, /* 31 - none */ 8241488Smckusick }; 8341488Smckusick 8441488Smckusick main() 8541488Smckusick { 8641488Smckusick register type, part, unit, io; 8741488Smckusick register char *cp; 8841488Smckusick 8941488Smckusick printf("\nBoot\n"); 9041488Smckusick #ifdef JUSTASK 9141488Smckusick howto = RB_ASKNAME|RB_SINGLE; 9241488Smckusick #else 9341488Smckusick type = (devtype >> B_TYPESHIFT) & B_TYPEMASK; 9441488Smckusick unit = (devtype >> B_UNITSHIFT) & B_UNITMASK; 9541488Smckusick unit += 8 * ((devtype >> B_ADAPTORSHIFT) & B_ADAPTORMASK); 9641488Smckusick part = (devtype >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 9741488Smckusick if ((howto & RB_ASKNAME) == 0) { 9841488Smckusick if ((devtype & B_MAGICMASK) != B_DEVMAGIC) { 9941488Smckusick /* 10041488Smckusick * we have to map the ROM device type codes 10141488Smckusick * to Unix major device numbers. 10241488Smckusick */ 10341488Smckusick type = rom2mdev[*(char *)MSUS & 0x1f]; 10441488Smckusick devtype = (devtype &~ (B_TYPEMASK << B_TYPESHIFT)) 10541488Smckusick | (type << B_TYPESHIFT); 10641488Smckusick } 10741488Smckusick if (type >= 0 && type <= MAXTYPE && devname[type][0]) { 10841488Smckusick cp = line; 10941488Smckusick *cp++ = devname[type][0]; 11041488Smckusick *cp++ = devname[type][1]; 11141488Smckusick *cp++ = '('; 11241488Smckusick if (unit >= 10) 11341488Smckusick *cp++ = unit / 10 + '0'; 11441488Smckusick *cp++ = unit % 10 + '0'; 11541488Smckusick *cp++ = ','; 11641488Smckusick *cp++ = part + '0'; 11741488Smckusick *cp++ = ')'; 11841488Smckusick strcpy(cp, UNIX); 11941488Smckusick } else 12041488Smckusick howto = RB_SINGLE|RB_ASKNAME; 12141488Smckusick } 12241488Smckusick #endif 12341488Smckusick for (;;) { 12441488Smckusick if (!noconsole && (howto & RB_ASKNAME)) { 12541488Smckusick printf(": "); 12641488Smckusick gets(line); 12741488Smckusick } else 12841488Smckusick printf(": %s\n", line); 12941488Smckusick io = open(line, 0); 13041488Smckusick if (io >= 0) { 13141488Smckusick #ifndef INSECURE 13241488Smckusick (void) fstat(io, &sb); 13341488Smckusick if (sb.st_uid || (sb.st_mode & 2)) { 13441488Smckusick printf("non-secure file, will not load\n"); 13541488Smckusick howto = RB_SINGLE|RB_ASKNAME; 13641488Smckusick continue; 13741488Smckusick } 13841488Smckusick #endif 13941488Smckusick if (howto & RB_ASKNAME) { 14041488Smckusick /* 14141488Smckusick * Build up devtype register to pass on to 14241488Smckusick * booted program. 14341488Smckusick */ 14441488Smckusick cp = line; 14541488Smckusick for (type = 0; type <= MAXTYPE; type++) 14641488Smckusick if ((devname[type][0] == cp[0]) && 14741488Smckusick (devname[type][1] == cp[1])) 14841488Smckusick break; 14941488Smckusick if (type <= MAXTYPE) { 15041488Smckusick cp += 3; 15141488Smckusick unit = *cp++ - '0'; 15241488Smckusick if (*cp >= '0' && *cp <= '9') 15341488Smckusick unit = unit * 10 + *cp++ - '0'; 15441488Smckusick cp++; 15541488Smckusick part = atol(cp); 15641488Smckusick devtype = B_MAKEDEV(unit >> 3, unit & 7, part, type); 15741488Smckusick } 15841488Smckusick } 15941488Smckusick devtype |= B_DEVMAGIC; 16041488Smckusick copyunix(howto, devtype, io); 16141488Smckusick close(io); 16241488Smckusick howto = RB_SINGLE|RB_ASKNAME; 16341488Smckusick } 16441488Smckusick bad: 16541488Smckusick if (++retry > 2) 16641488Smckusick howto = RB_SINGLE|RB_ASKNAME; 16741488Smckusick } 16841488Smckusick } 16941488Smckusick 17041488Smckusick /*ARGSUSED*/ 17141488Smckusick copyunix(howto, devtype, io) 17241488Smckusick register howto; /* d7 contains boot flags */ 17341488Smckusick register devtype; /* d6 contains boot device */ 17441488Smckusick register io; 17541488Smckusick { 17641488Smckusick struct exec x; 17741488Smckusick register int i; 17841488Smckusick register char *load; /* a5 contains load addr for unix */ 17941488Smckusick register char *addr; 18041488Smckusick 18141488Smckusick i = read(io, (char *)&x, sizeof x); 18241488Smckusick if (i != sizeof x || 18341488Smckusick (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410)) 18441488Smckusick _stop("Bad format\n"); 18541488Smckusick printf("%d", x.a_text); 18641488Smckusick if (x.a_magic == 0413 && lseek(io, 0x400, 0) == -1) 18741488Smckusick goto shread; 18841488Smckusick load = addr = lowram; 18941488Smckusick if (read(io, (char *)addr, x.a_text) != x.a_text) 19041488Smckusick goto shread; 19141488Smckusick addr += x.a_text; 19241488Smckusick if (x.a_magic == 0413 || x.a_magic == 0410) 19341488Smckusick while ((int)addr & CLOFSET) 19441488Smckusick *addr++ = 0; 19541488Smckusick printf("+%d", x.a_data); 19641488Smckusick if (read(io, addr, x.a_data) != x.a_data) 19741488Smckusick goto shread; 19841488Smckusick addr += x.a_data; 19941488Smckusick printf("+%d", x.a_bss); 20041488Smckusick x.a_bss += 128*512; /* slop */ 20141488Smckusick for (i = 0; i < x.a_bss; i++) 20241488Smckusick *addr++ = 0; 20341488Smckusick x.a_entry += (int)lowram; 20441488Smckusick printf(" start 0x%x\n", x.a_entry); 20541488Smckusick #ifdef __GNUC__ 20641488Smckusick asm(" movl %0,d7" : : "m" (howto)); 20741488Smckusick asm(" movl %0,d6" : : "m" (devtype)); 20841488Smckusick asm(" movl %0,a5" : : "a" (load)); 20941488Smckusick #endif 21041488Smckusick (*((int (*)()) x.a_entry))(); 21141488Smckusick exit(); 21241488Smckusick shread: 21341488Smckusick _stop("Short read\n"); 21441488Smckusick } 215