|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* ! 26: * Copyright (c) 1987, 1988 NeXT, Inc. ! 27: * ! 28: * HISTORY ! 29: * ! 30: * Tue Dec 7 17:37:14 PST 1993 Matt Watson (mwatson) at NeXT ! 31: * Added netboot capability. ! 32: * ! 33: * 07-Apr-90 Doug Mitchell at NeXT ! 34: * Added fd driver support. ! 35: * ! 36: * 16-Feb-88 John Seamons (jks) at NeXT ! 37: * Updated to Mach release 2. ! 38: * ! 39: * 29-Oct-87 Robert V. Baron (rvb) at Carnegie-Mellon University ! 40: * Allow root to be an arbitrary slice on the drive. ! 41: * ! 42: * 14-Nov-86 John Seamons (jks) at NeXT ! 43: * Ported to NeXT. ! 44: */ ! 45: ! 46: #import <sys/param.h> ! 47: #import <sys/conf.h> ! 48: #import <sys/buf.h> ! 49: #import <sys/time.h> ! 50: #import <sys/systm.h> ! 51: #import <sys/mount.h> ! 52: #import <sys/reboot.h> ! 53: #import <sys/vnode.h> ! 54: #import <sys/socket.h> ! 55: #import <sys/errno.h> ! 56: #import <sys/ioctl.h> ! 57: #import <net/if.h> ! 58: #import <netinet/in_systm.h> ! 59: #import <netinet/in.h> ! 60: #import <netinet/in_var.h> ! 61: #import <netinet/ip.h> ! 62: #import <netinet/udp.h> ! 63: #import <netinet/if_ether.h> ! 64: #import <machdep/i386/kernBootStruct.h> ! 65: #import <driverkit/kernelDriver.h> ! 66: #import <bsd/dev/scsireg.h> ! 67: /* ! 68: * Hack to avoid collision with vnode.h! ! 69: */ ! 70: #undef IO_UNIT ! 71: #import <driverkit/IODeviceParams.h> ! 72: #import <driverkit/SCSIDisk.h> ! 73: ! 74: extern int ffs_mountroot(); ! 75: ! 76: #ifdef NFSCLIENT ! 77: extern char *nfsbootdevname; /* nfs_boot.c */ ! 78: extern int nfs_mountroot(); /* nfs_vfsops.c */ ! 79: #else /* NFSCLIENT */ ! 80: static char *nfsbootdevname; ! 81: static int nfs_mountroot() { return ENOSYS; } ! 82: #endif /* NFSCLIENT */ ! 83: ! 84: extern int (*mountroot)(); ! 85: ! 86: extern char hostname[], boot_info[], boot_dev[]; ! 87: extern char domainname[]; ! 88: extern struct xdr_ops xdrmbuf_ops; ! 89: extern int hostnamelen; ! 90: char rootdevice[8]; ! 91: ! 92: int boottype = 0, boothowto = RB_DEBUG; ! 93: ! 94: /* ! 95: * Generic configuration; all in one ! 96: */ ! 97: extern long dumplo; ! 98: int dmmin, dmmax, dmtext; ! 99: ! 100: struct genericconf { ! 101: char *gc_name; ! 102: dev_t gc_root; /* NODEV means remote root */ ! 103: } genericconf[] = { ! 104: { "sd", makedev(6, 0) }, ! 105: { "hd", makedev(3, 0) }, ! 106: { "fd", makedev(1, 0) }, ! 107: { "en", NODEV }, ! 108: { "tr", NODEV }, ! 109: { 0 }, ! 110: }; ! 111: ! 112: static struct genericconf *gc; ! 113: static int scsiControllerDetected(void); ! 114: ! 115: setconf() ! 116: { ! 117: extern char init_args[]; ! 118: int devmajor, devminor; ! 119: int unit=0; ! 120: int slice = 0; ! 121: char *name, root_name[128]; ! 122: KERNBOOTSTRUCT *kernBootStruct = (KERNBOOTSTRUCT *)KERNSTRUCT_ADDR; ! 123: char scsiName[10]; ! 124: int panelUp = 0; ! 125: ! 126: if (kernBootStruct->magicCookie != KERNBOOTMAGIC) ! 127: panic("invalid boot struct"); ! 128: ! 129: if ((boothowto & RB_ASKNAME) || rootdevice[0]) { ! 130: retry: ! 131: if (boothowto & RB_ASKNAME) { ! 132: if( 0 == panelUp) { ! 133: DoSafeAlert("Root Device?", "", TRUE); ! 134: panelUp = 1; ! 135: } ! 136: printf("root device? "); ! 137: name = root_name; ! 138: gets(name, name); ! 139: } else { ! 140: /* ! 141: * If we've been asked for CDROM, find the ! 142: * corresponding sd device. ! 143: */ ! 144: if(!strcmp("cdrom", rootdevice)) { ! 145: id scsiId = nil; ! 146: int i; ! 147: IOReturn rtn; ! 148: unsigned char inquiryType; ! 149: ! 150: for(i=0; i<16; i++) { ! 151: sprintf(scsiName, "sd%d", i); ! 152: rtn = IOGetObjectForDeviceName(scsiName, ! 153: &scsiId); ! 154: if(rtn) { ! 155: break; // no more sd's ! 156: } ! 157: inquiryType = [scsiId inquiryDeviceType]; ! 158: if(inquiryType == DEVTYPE_CDROM) { ! 159: name = scsiName; ! 160: goto name_found; ! 161: } ! 162: /* else continue to next sd */ ! 163: } ! 164: if (scsiControllerDetected()) ! 165: printf("No CD-ROM drive found\n"); ! 166: else ! 167: printf("No SCSI controller or CD-ROM drive found\n"); ! 168: goto bad; ! 169: } ! 170: else { ! 171: name = rootdevice; ! 172: } ! 173: name_found: ! 174: printf ("root on %s\n", name); ! 175: } ! 176: for (gc = genericconf; gc->gc_name; gc++) ! 177: if (gc->gc_name[0] == name[0] && ! 178: gc->gc_name[1] == name[1]) ! 179: goto gotit; ! 180: goto bad; ! 181: ! 182: gotit: ! 183: if (gc->gc_root == NODEV) { ! 184: goto found; ! 185: } ! 186: if (name[2] >= '0' && name[2] <= '7') { ! 187: if (name[3] >= 'a' && name[3] <= 'h') { ! 188: slice = name[3] - 'a'; ! 189: } else if (name[3]) { ! 190: printf("bad partition number\n"); ! 191: goto bad; ! 192: } ! 193: unit = name[2] - '0'; ! 194: goto found; ! 195: } ! 196: printf("bad/missing unit number\n"); ! 197: bad: ! 198: for (gc = genericconf; gc->gc_name; gc++) ! 199: printf("%s%s%%d", ! 200: (gc == genericconf)?"use ": ! 201: (((gc+1)->gc_name)?", ":" or "), ! 202: gc->gc_name); ! 203: printf("\n"); ! 204: boothowto |= RB_ASKNAME; ! 205: goto retry; ! 206: found: ! 207: if (gc->gc_root == NODEV) { ! 208: printf("mounting nfs root\n"); ! 209: nfsbootdevname = rootdevice; ! 210: mountroot = nfs_mountroot; ! 211: rootdev = NODEV; ! 212: } else { ! 213: mountroot = ffs_mountroot; ! 214: gc->gc_root = makedev(major(gc->gc_root), unit*8+slice); ! 215: rootdev = gc->gc_root; ! 216: } ! 217: } ! 218: else ! 219: { ! 220: boottype = kernBootStruct->rootdev; ! 221: devmajor = (boottype >> B_TYPESHIFT) & B_TYPEMASK; ! 222: devminor = (boottype >> B_PARTITIONSHIFT) & B_PARTITIONMASK; ! 223: devminor |= (((boottype >> B_UNITSHIFT) & B_UNITMASK) << 3); ! 224: ! 225: rootdev = makedev(devmajor, devminor); ! 226: } ! 227: printf("rootdev %x, howto %x\n", rootdev, boothowto); ! 228: ! 229: if( panelUp) ! 230: alert_done(); ! 231: } ! 232: ! 233: gets(cp, lp) ! 234: char *cp, *lp; ! 235: { ! 236: register c; ! 237: ! 238: for (;;) { ! 239: c = cngetc() & 0177; ! 240: switch (c) { ! 241: case '\n': ! 242: case '\r': ! 243: *lp++ = '\0'; ! 244: return; ! 245: case '\177': ! 246: if (lp == cp) { ! 247: cnputc('\b'); ! 248: continue; ! 249: } ! 250: cnputc('\b'); ! 251: cnputc('\b'); ! 252: /* fall into ... */ ! 253: case '\b': ! 254: if (lp == cp) { ! 255: cnputc('\b'); ! 256: continue; ! 257: } ! 258: cnputc(' '); ! 259: cnputc('\b'); ! 260: lp--; ! 261: continue; ! 262: case '@': ! 263: case 'u'&037: ! 264: lp = cp; ! 265: cnputc('\n'); ! 266: continue; ! 267: default: ! 268: *lp++ = c; ! 269: } ! 270: } ! 271: } ! 272: ! 273: /* ! 274: * If booted with ASKNAME, prompt on the console for a filesystem ! 275: * name and return it. ! 276: */ ! 277: getfsname(askfor, name) ! 278: char *askfor; ! 279: char *name; ! 280: { ! 281: ! 282: if (boothowto & RB_ASKNAME) { ! 283: printf("%s key [%s]: ", askfor, askfor); ! 284: gets(name, name); ! 285: } ! 286: } ! 287: ! 288: static int ! 289: scsiControllerDetected(void) ! 290: { ! 291: IOReturn rtn; ! 292: IOObjectNumber i; ! 293: IOString name, kind; ! 294: Protocol **protos; ! 295: id deviceId; ! 296: int j; ! 297: ! 298: protos = [SCSIDisk requiredProtocols]; ! 299: if (protos == NULL || *protos == nil) { ! 300: /* ! 301: * We can't search for a SCSI adapter, ! 302: * so don't say we didn't find one. ! 303: */ ! 304: return 1; ! 305: } ! 306: for(i = 0; ; i++) { ! 307: rtn = [IODevice lookupByObjectNumber:i deviceKind:&kind ! 308: deviceName:&name]; ! 309: if (rtn != IO_R_SUCCESS && rtn != IO_R_OFFLINE) ! 310: break; ! 311: rtn = IOGetObjectForDeviceName(name, &deviceId); ! 312: if (rtn == IO_R_SUCCESS) { ! 313: int conforms = 1; ! 314: /* Check to see if it implements the correct protocols. */ ! 315: for(j=0; protos[j]; j++) { ! 316: if(![deviceId conformsTo:protos[j]]) { ! 317: conforms = 0; ! 318: break; ! 319: } ! 320: } ! 321: if (conforms) ! 322: return 1; ! 323: } ! 324: } ! 325: return 0; ! 326: } ! 327: ! 328: #if 0 ! 329: int ! 330: initrootnet() ! 331: { ! 332: struct socket *so = NULL; ! 333: struct ifreq ifr; ! 334: int error; ! 335: extern struct in_ifaddr *in_ifaddr; ! 336: int message = 0; ! 337: ! 338: /* Is there already a primary network? */ ! 339: if (in_ifaddr && !(in_ifaddr->ia_ifp->if_flags & IFF_LOOPBACK)) ! 340: return(0); ! 341: ! 342: ifr.ifr_name[0] = gc->gc_name[0]; ! 343: ifr.ifr_name[1] = gc->gc_name[1]; ! 344: ifr.ifr_name[2] = '0'; ! 345: ifr.ifr_name[3] = '\0'; ! 346: error = socreate(AF_INET, &so, SOCK_DGRAM, 0); ! 347: if (error) { ! 348: printf("initrootnet: socreate failed\n"); ! 349: goto errout; ! 350: } ! 351: ifr.ifr_addr.sa_family = AF_INET; ! 352: while (error = ifioctl(so, SIOCAUTOADDR, (caddr_t)&ifr)) { ! 353: if (error == ETIMEDOUT) { ! 354: if (!message) { ! 355: printf("initrootnet: BOOTP timed out, still trying...\n"); ! 356: message++; ! 357: } ! 358: } else { ! 359: printf("initrootnet: autoaddr failed\n"); ! 360: goto errout; ! 361: } ! 362: } ! 363: if (message) { ! 364: printf("initrootnet: BOOTP [OK].\n"); ! 365: } ! 366: printf("primary network interface: %s [%s]\n", ifr.ifr_name, ! 367: inet_ntoa(&((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr)); ! 368: errout: ! 369: if (so) { ! 370: soclose(so); ! 371: } ! 372: return(error); ! 373: } ! 374: #endif /* 0 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.