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