1*78713aceSkarels /* boot.c 1.5 86/12/18 */ 28e3d4093Ssam 38e3d4093Ssam #include "../machine/mtpr.h" 48e3d4093Ssam 58e3d4093Ssam #include "param.h" 68e3d4093Ssam #include "inode.h" 78e3d4093Ssam #include "fs.h" 88e3d4093Ssam #include "vm.h" 98e3d4093Ssam #include "saio.h" 108e3d4093Ssam #include "reboot.h" 118e3d4093Ssam 128e3d4093Ssam #include <a.out.h> 138e3d4093Ssam 148e3d4093Ssam /* 158e3d4093Ssam * Boot program... arguments passed in r10 and r11 determine 168e3d4093Ssam * whether boot stops to ask for system name and which device 178e3d4093Ssam * boot comes from. 188e3d4093Ssam */ 198e3d4093Ssam 208e3d4093Ssam /* Types in r10 specifying major device */ 21988e96f5Ssam char devname[][2] = { 22988e96f5Ssam 0, 0, /* 0 = ud */ 23977ec1dbSkarels 'd','k', /* 1 = vd/dk */ 24988e96f5Ssam 0, 0, /* 2 = xp */ 25988e96f5Ssam 'c','y', /* 3 = cy */ 268e3d4093Ssam }; 27988e96f5Ssam #define MAXTYPE (sizeof(devname) / sizeof(devname[0])) 28977ec1dbSkarels #define DEV_DFLT 1 /* vd/dk */ 298e3d4093Ssam 30988e96f5Ssam #define UNIX "vmunix" 318e3d4093Ssam char line[100]; 328e3d4093Ssam 338e3d4093Ssam int retry = 0; 348e3d4093Ssam 358e3d4093Ssam main() 368e3d4093Ssam { 378e3d4093Ssam register dummy; /* skip r12 */ 388e3d4093Ssam register howto, devtype; /* howto=r11, devtype=r10 */ 39988e96f5Ssam int io, i; 40988e96f5Ssam register type, part, unit; 41988e96f5Ssam register char *cp; 42988e96f5Ssam long atol(); 43988e96f5Ssam 448e3d4093Ssam 458e3d4093Ssam #ifdef lint 468e3d4093Ssam howto = 0; devtype = 0; 478e3d4093Ssam #endif 488e3d4093Ssam #ifdef JUSTASK 498e3d4093Ssam howto = RB_ASKNAME|RB_SINGLE; 50988e96f5Ssam #else 51977ec1dbSkarels if ((devtype & B_MAGICMASK) != B_DEVMAGIC) 52977ec1dbSkarels devtype = DEV_DFLT << B_TYPESHIFT; /* unit, partition 0 */ 53988e96f5Ssam type = (devtype >> B_TYPESHIFT) & B_TYPEMASK; 54988e96f5Ssam unit = (devtype >> B_UNITSHIFT) & B_UNITMASK; 55988e96f5Ssam unit += 8 * ((devtype >> B_ADAPTORSHIFT) & B_ADAPTORMASK); 56988e96f5Ssam part = (devtype >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 57988e96f5Ssam if ((howto & RB_ASKNAME) == 0) { 58988e96f5Ssam if (type >= 0 && type <= MAXTYPE && devname[type][0]) { 59988e96f5Ssam cp = line; 60988e96f5Ssam *cp++ = devname[type][0]; 61988e96f5Ssam *cp++ = devname[type][1]; 62988e96f5Ssam *cp++ = '('; 63988e96f5Ssam if (unit >= 10) 64988e96f5Ssam *cp++ = unit / 10 + '0'; 65988e96f5Ssam *cp++ = unit % 10 + '0'; 66988e96f5Ssam *cp++ = ','; 67977ec1dbSkarels if (part >= 10) 68977ec1dbSkarels *cp++ = part / 10 + '0'; 69977ec1dbSkarels *cp++ = part % 10 + '0'; 70988e96f5Ssam *cp++ = ')'; 71988e96f5Ssam strcpy(cp, UNIX); 72988e96f5Ssam } else 73988e96f5Ssam howto = RB_SINGLE|RB_ASKNAME; 74988e96f5Ssam } 758e3d4093Ssam #endif 768e3d4093Ssam for (;;) { 77988e96f5Ssam printf("\nBoot\n"); 788e3d4093Ssam if (howto & RB_ASKNAME) { 798e3d4093Ssam printf(": "); 808e3d4093Ssam gets(line); 818e3d4093Ssam } else 828e3d4093Ssam printf(": %s\n", line); 838e3d4093Ssam io = open(line, 0); 84988e96f5Ssam if (io >= 0) { 85988e96f5Ssam if (howto & RB_ASKNAME) { 86988e96f5Ssam /* 87988e96f5Ssam * Build up devtype register to pass on to 88988e96f5Ssam * booted program. 89988e96f5Ssam */ 90988e96f5Ssam cp = line; 91988e96f5Ssam for (i = 0; i <= MAXTYPE; i++) 92988e96f5Ssam if ((devname[i][0] == cp[0]) && 93988e96f5Ssam (devname[i][1] == cp[1])) 94988e96f5Ssam break; 95988e96f5Ssam if (i <= MAXTYPE) { 96988e96f5Ssam devtype = i << B_TYPESHIFT; 97988e96f5Ssam cp += 3; 98988e96f5Ssam i = *cp++ - '0'; 99988e96f5Ssam if (*cp >= '0' && *cp <= '9') 100988e96f5Ssam i = i * 10 + *cp++ - '0'; 101988e96f5Ssam cp++; 102988e96f5Ssam devtype |= ((i % 8) << B_UNITSHIFT); 103988e96f5Ssam devtype |= ((i / 8) << B_ADAPTORSHIFT); 104988e96f5Ssam devtype |= atol(cp) << B_PARTITIONSHIFT; 105988e96f5Ssam } 106988e96f5Ssam } 107988e96f5Ssam devtype |= B_DEVMAGIC; 108988e96f5Ssam copyunix(howto, devtype, io); 109988e96f5Ssam close(io); 110988e96f5Ssam howto = RB_SINGLE|RB_ASKNAME; 111988e96f5Ssam } 1128e3d4093Ssam if (++retry > 2) 1138e3d4093Ssam howto |= RB_SINGLE|RB_ASKNAME; 1148e3d4093Ssam } 1158e3d4093Ssam } 1168e3d4093Ssam 1178e3d4093Ssam /*ARGSUSED*/ 118988e96f5Ssam copyunix(howto, devtype, io) 119988e96f5Ssam register io, howto, devtype; /* NOTE ORDER */ 1208e3d4093Ssam { 121097b37ecSsam register int esym; /* must be r9 */ 1228e3d4093Ssam register int i; 123988e96f5Ssam register char *addr; 124097b37ecSsam struct exec x; 1258e3d4093Ssam 1268e3d4093Ssam i = read(io, (char *)&x, sizeof x); 1278e3d4093Ssam if (i != sizeof x || 1288e3d4093Ssam (x.a_magic != 0407 && x.a_magic != 0413 && x.a_magic != 0410)) 1298e3d4093Ssam _stop("Bad format\n"); 1308e3d4093Ssam printf("%d", x.a_text); 1318e3d4093Ssam if (x.a_magic == 0413 && lseek(io, 0x400, 0) == -1) 1328e3d4093Ssam goto shread; 133*78713aceSkarels if (read(io, (char *)RELOC, x.a_text) != x.a_text) 1348e3d4093Ssam goto shread; 135*78713aceSkarels addr = (char *)(x.a_text + RELOC); 1368e3d4093Ssam if (x.a_magic == 0413 || x.a_magic == 0410) 1378e3d4093Ssam while ((int)addr & CLOFSET) 1388e3d4093Ssam *addr++ = 0; 1398e3d4093Ssam printf("+%d", x.a_data); 1408e3d4093Ssam if (read(io, addr, x.a_data) != x.a_data) 1418e3d4093Ssam goto shread; 1428e3d4093Ssam addr += x.a_data; 1438e3d4093Ssam printf("+%d", x.a_bss); 144097b37ecSsam if (howto & RB_KDB && x.a_syms) { 145097b37ecSsam for (i = 0; i < x.a_bss; i++) 146097b37ecSsam *addr++ = 0; 147097b37ecSsam *(int *)addr = x.a_syms; /* symbol table size */ 148097b37ecSsam addr += sizeof (int); 149097b37ecSsam printf("[+%d", x.a_syms); 150097b37ecSsam if (read(io, addr, x.a_syms) != x.a_syms) 151097b37ecSsam goto shread; 152097b37ecSsam addr += x.a_syms; 153097b37ecSsam if (read(io, addr, sizeof (int)) != sizeof (int)) 154097b37ecSsam goto shread; 155097b37ecSsam i = *(int *)addr - sizeof (int); /* string table size */ 156097b37ecSsam addr += sizeof (int); 157097b37ecSsam printf("+%d]", i); 158097b37ecSsam if (read(io, addr, i) != i) 159097b37ecSsam goto shread; 160097b37ecSsam addr += i; 161097b37ecSsam esym = roundup((int)addr, sizeof (int)); 162097b37ecSsam x.a_bss = 0; 163097b37ecSsam } else 164097b37ecSsam howto &= ~RB_KDB; 1658e3d4093Ssam x.a_bss += 32*1024; /* slop */ 1668e3d4093Ssam for (i = 0; i < x.a_bss; i++) 1678e3d4093Ssam *addr++ = 0; 1688e3d4093Ssam x.a_entry &= 0x1fffffff; 1698e3d4093Ssam printf(" start 0x%x\n", x.a_entry); 1708e3d4093Ssam mtpr(PADC, 0); /* Purge data cache */ 1718e3d4093Ssam mtpr(PACC, 0); /* Purge code cache */ 1728e3d4093Ssam mtpr(DCR, 1); /* Enable data cache */ 1738e3d4093Ssam (*((int (*)()) x.a_entry))(); 174988e96f5Ssam return; 1758e3d4093Ssam shread: 1768e3d4093Ssam _stop("Short read\n"); 1778e3d4093Ssam } 178