1*30182Ssam /* boot.c 1.4 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 */ 2330177Skarels 'd','k', /* 1 = vd/dk */ 2429565Ssam 0, 0, /* 2 = xp */ 2529565Ssam 'c','y', /* 3 = cy */ 2625865Ssam }; 2729565Ssam #define MAXTYPE (sizeof(devname) / sizeof(devname[0])) 2830177Skarels #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 5130177Skarels if ((devtype & B_MAGICMASK) != B_DEVMAGIC) 5230177Skarels 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++ = ','; 6730177Skarels if (part >= 10) 6830177Skarels *cp++ = part / 10 + '0'; 6930177Skarels *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 { 121*30182Ssam register int esym; /* must be r9 */ 12225865Ssam register int i; 12329565Ssam register char *addr; 124*30182Ssam struct exec x; 12525865Ssam 12625865Ssam i = read(io, (char *)&x, sizeof x); 12725865Ssam if (i != sizeof x || 12825865Ssam (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410)) 12925865Ssam _stop("Bad format\n"); 13025865Ssam printf("%d", x.a_text); 13125865Ssam if (x.a_magic == 0413 && lseek(io, 0x400, 0) == -1) 13225865Ssam goto shread; 13325865Ssam if (read(io, (char *)0x800, x.a_text) != x.a_text) 13425865Ssam goto shread; 13525865Ssam addr = (char *)(x.a_text + 0x800); 13625865Ssam if (x.a_magic == 0413 || x.a_magic == 0410) 13725865Ssam while ((int)addr & CLOFSET) 13825865Ssam *addr++ = 0; 13925865Ssam printf("+%d", x.a_data); 14025865Ssam if (read(io, addr, x.a_data) != x.a_data) 14125865Ssam goto shread; 14225865Ssam addr += x.a_data; 14325865Ssam printf("+%d", x.a_bss); 144*30182Ssam if (howto & RB_KDB && x.a_syms) { 145*30182Ssam for (i = 0; i < x.a_bss; i++) 146*30182Ssam *addr++ = 0; 147*30182Ssam *(int *)addr = x.a_syms; /* symbol table size */ 148*30182Ssam addr += sizeof (int); 149*30182Ssam printf("[+%d", x.a_syms); 150*30182Ssam if (read(io, addr, x.a_syms) != x.a_syms) 151*30182Ssam goto shread; 152*30182Ssam addr += x.a_syms; 153*30182Ssam if (read(io, addr, sizeof (int)) != sizeof (int)) 154*30182Ssam goto shread; 155*30182Ssam i = *(int *)addr - sizeof (int); /* string table size */ 156*30182Ssam addr += sizeof (int); 157*30182Ssam printf("+%d]", i); 158*30182Ssam if (read(io, addr, i) != i) 159*30182Ssam goto shread; 160*30182Ssam addr += i; 161*30182Ssam esym = roundup((int)addr, sizeof (int)); 162*30182Ssam x.a_bss = 0; 163*30182Ssam } else 164*30182Ssam howto &= ~RB_KDB; 16525865Ssam x.a_bss += 32*1024; /* slop */ 16625865Ssam for (i = 0; i < x.a_bss; i++) 16725865Ssam *addr++ = 0; 16825865Ssam x.a_entry &= 0x1fffffff; 16925865Ssam printf(" start 0x%x\n", x.a_entry); 17025865Ssam mtpr(PADC, 0); /* Purge data cache */ 17125865Ssam mtpr(PACC, 0); /* Purge code cache */ 17229565Ssam mtpr(DCR, 1); /* Enable data cache */ 17325865Ssam (*((int (*)()) x.a_entry))(); 17429565Ssam return; 17525865Ssam shread: 17625865Ssam _stop("Short read\n"); 17725865Ssam } 178