1*30177Skarels /* boot.c 1.3 86/11/25 */ 225865Ssam 325865Ssam #include "../machine/mtpr.h" 425865Ssam 525865Ssam #include "param.h" 625865Ssam #include "inode.h" 725865Ssam #include "fs.h" 825865Ssam #include "vm.h" 925865Ssam #include "saio.h" 1025865Ssam #include "reboot.h" 1125865Ssam 1225865Ssam #include <a.out.h> 1325865Ssam 1425865Ssam /* 1525865Ssam * Boot program... arguments passed in r10 and r11 determine 1625865Ssam * whether boot stops to ask for system name and which device 1725865Ssam * boot comes from. 1825865Ssam */ 1925865Ssam 2025865Ssam /* Types in r10 specifying major device */ 2129565Ssam char devname[][2] = { 2229565Ssam 0, 0, /* 0 = ud */ 23*30177Skarels 'd','k', /* 1 = vd/dk */ 2429565Ssam 0, 0, /* 2 = xp */ 2529565Ssam 'c','y', /* 3 = cy */ 2625865Ssam }; 2729565Ssam #define MAXTYPE (sizeof(devname) / sizeof(devname[0])) 28*30177Skarels #define DEV_DFLT 1 /* vd/dk */ 2925865Ssam 3029565Ssam #define UNIX "vmunix" 3125865Ssam char line[100]; 3225865Ssam 3325865Ssam int retry = 0; 3425865Ssam 3525865Ssam main() 3625865Ssam { 3725865Ssam register dummy; /* skip r12 */ 3825865Ssam register howto, devtype; /* howto=r11, devtype=r10 */ 3929565Ssam int io, i; 4029565Ssam register type, part, unit; 4129565Ssam register char *cp; 4229565Ssam long atol(); 4325865Ssam 4429565Ssam 4525865Ssam #ifdef lint 4625865Ssam howto = 0; devtype = 0; 4725865Ssam #endif 4825865Ssam #ifdef JUSTASK 4925865Ssam howto = RB_ASKNAME|RB_SINGLE; 5029565Ssam #else 51*30177Skarels if ((devtype & B_MAGICMASK) != B_DEVMAGIC) 52*30177Skarels devtype = DEV_DFLT << B_TYPESHIFT; /* unit, partition 0 */ 5329565Ssam type = (devtype >> B_TYPESHIFT) & B_TYPEMASK; 5429565Ssam unit = (devtype >> B_UNITSHIFT) & B_UNITMASK; 5529565Ssam unit += 8 * ((devtype >> B_ADAPTORSHIFT) & B_ADAPTORMASK); 5629565Ssam part = (devtype >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 5729565Ssam if ((howto & RB_ASKNAME) == 0) { 5829565Ssam if (type >= 0 && type <= MAXTYPE && devname[type][0]) { 5929565Ssam cp = line; 6029565Ssam *cp++ = devname[type][0]; 6129565Ssam *cp++ = devname[type][1]; 6229565Ssam *cp++ = '('; 6329565Ssam if (unit >= 10) 6429565Ssam *cp++ = unit / 10 + '0'; 6529565Ssam *cp++ = unit % 10 + '0'; 6629565Ssam *cp++ = ','; 67*30177Skarels if (part >= 10) 68*30177Skarels *cp++ = part / 10 + '0'; 69*30177Skarels *cp++ = part % 10 + '0'; 7029565Ssam *cp++ = ')'; 7129565Ssam strcpy(cp, UNIX); 7229565Ssam } else 7329565Ssam howto = RB_SINGLE|RB_ASKNAME; 7429565Ssam } 7525865Ssam #endif 7625865Ssam for (;;) { 7729565Ssam printf("\nBoot\n"); 7825865Ssam if (howto & RB_ASKNAME) { 7925865Ssam printf(": "); 8025865Ssam gets(line); 8125865Ssam } else 8225865Ssam printf(": %s\n", line); 8325865Ssam io = open(line, 0); 8429565Ssam if (io >= 0) { 8529565Ssam if (howto & RB_ASKNAME) { 8629565Ssam /* 8729565Ssam * Build up devtype register to pass on to 8829565Ssam * booted program. 8929565Ssam */ 9029565Ssam cp = line; 9129565Ssam for (i = 0; i <= MAXTYPE; i++) 9229565Ssam if ((devname[i][0] == cp[0]) && 9329565Ssam (devname[i][1] == cp[1])) 9429565Ssam break; 9529565Ssam if (i <= MAXTYPE) { 9629565Ssam devtype = i << B_TYPESHIFT; 9729565Ssam cp += 3; 9829565Ssam i = *cp++ - '0'; 9929565Ssam if (*cp >= '0' && *cp <= '9') 10029565Ssam i = i * 10 + *cp++ - '0'; 10129565Ssam cp++; 10229565Ssam devtype |= ((i % 8) << B_UNITSHIFT); 10329565Ssam devtype |= ((i / 8) << B_ADAPTORSHIFT); 10429565Ssam devtype |= atol(cp) << B_PARTITIONSHIFT; 10529565Ssam } 10629565Ssam } 10729565Ssam devtype |= B_DEVMAGIC; 10829565Ssam copyunix(howto, devtype, io); 10929565Ssam close(io); 11029565Ssam howto = RB_SINGLE|RB_ASKNAME; 11129565Ssam } 11225865Ssam if (++retry > 2) 11325865Ssam howto |= RB_SINGLE|RB_ASKNAME; 11425865Ssam } 11525865Ssam } 11625865Ssam 11725865Ssam /*ARGSUSED*/ 11829565Ssam copyunix(howto, devtype, io) 11929565Ssam register io, howto, devtype; /* NOTE ORDER */ 12025865Ssam { 12125865Ssam struct exec x; 12225865Ssam register int i; 12329565Ssam register char *addr; 12425865Ssam 12525865Ssam i = read(io, (char *)&x, sizeof x); 12625865Ssam if (i != sizeof x || 12725865Ssam (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410)) 12825865Ssam _stop("Bad format\n"); 12925865Ssam printf("%d", x.a_text); 13025865Ssam if (x.a_magic == 0413 && lseek(io, 0x400, 0) == -1) 13125865Ssam goto shread; 13225865Ssam if (read(io, (char *)0x800, x.a_text) != x.a_text) 13325865Ssam goto shread; 13425865Ssam addr = (char *)(x.a_text + 0x800); 13525865Ssam if (x.a_magic == 0413 || x.a_magic == 0410) 13625865Ssam while ((int)addr & CLOFSET) 13725865Ssam *addr++ = 0; 13825865Ssam printf("+%d", x.a_data); 13925865Ssam if (read(io, addr, x.a_data) != x.a_data) 14025865Ssam goto shread; 14125865Ssam addr += x.a_data; 14225865Ssam printf("+%d", x.a_bss); 14325865Ssam x.a_bss += 32*1024; /* slop */ 14425865Ssam for (i = 0; i < x.a_bss; i++) 14525865Ssam *addr++ = 0; 14625865Ssam x.a_entry &= 0x1fffffff; 14725865Ssam printf(" start 0x%x\n", x.a_entry); 14825865Ssam mtpr(PADC, 0); /* Purge data cache */ 14925865Ssam mtpr(PACC, 0); /* Purge code cache */ 15029565Ssam mtpr(DCR, 1); /* Enable data cache */ 15125865Ssam (*((int (*)()) x.a_entry))(); 15229565Ssam return; 15325865Ssam shread: 15425865Ssam _stop("Short read\n"); 15525865Ssam } 156