|
|
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/ppc/kernBootStruct.h> ! 65: #import <machdep/ppc/powermac.h> ! 66: #import <driverkit/kernelDriver.h> ! 67: #import <driverkit/IODiskPartition.h> ! 68: #import <bsd/dev/scsireg.h> ! 69: /* ! 70: * Hack to avoid collision with vnode.h! ! 71: */ ! 72: #undef IO_UNIT ! 73: #import <driverkit/IODeviceParams.h> ! 74: #import <driverkit/SCSIDisk.h> ! 75: ! 76: extern int ffs_mountroot(); ! 77: ! 78: #ifdef NFSCLIENT ! 79: extern char *nfsbootdevname; /* nfs_boot.c */ ! 80: extern int nfs_mountroot(); /* nfs_vfsops.c */ ! 81: #else /* NFSCLIENT */ ! 82: static char *nfsbootdevname; ! 83: static int nfs_mountroot() { return ENOSYS; } ! 84: #endif /* NFSCLIENT */ ! 85: ! 86: extern int (*mountroot)(); ! 87: ! 88: extern char hostname[], boot_info[], boot_dev[]; ! 89: extern char domainname[]; ! 90: extern struct xdr_ops xdrmbuf_ops; ! 91: extern int hostnamelen; ! 92: char rootdevice[ 128 ]; ! 93: ! 94: // wait until 30 seconds after probe for non-ready root disk ! 95: #define MAX_DISK_PROBE_TIME 30 ! 96: ! 97: int boottype = 0, boothowto = RB_DEBUG; ! 98: ! 99: /* ! 100: * Generic configuration; all in one ! 101: */ ! 102: extern long dumplo; ! 103: int dmmin, dmmax, dmtext; ! 104: ! 105: struct genericconf { ! 106: char *gc_name; ! 107: dev_t gc_root; /* NODEV means remote root */ ! 108: } genericconf[] = { ! 109: { "sd", makedev(6, 0) }, ! 110: { "hd", makedev(3, 0) }, ! 111: { "fd", makedev(1, 0) }, ! 112: { "en", NODEV }, ! 113: { "tr", NODEV }, ! 114: { 0 }, ! 115: }; ! 116: ! 117: static struct genericconf *gc; ! 118: static int scsiControllerDetected(void); ! 119: ! 120: #include <machdep/ppc/DeviceTree.h> ! 121: ! 122: id ! 123: SearchForDeviceByPath( char * path, char ** firstArg ) ! 124: { ! 125: IOReturn err; ! 126: int objectNum = 0; ! 127: id dev = nil; ! 128: char * tail; ! 129: char c; ! 130: ! 131: if( firstArg) ! 132: *firstArg = NULL; ! 133: do { ! 134: err = [IODevice lookupByObjectNumber:objectNum++ instance:&dev]; ! 135: if( err != IO_R_SUCCESS) ! 136: continue; ! 137: ! 138: if( (tail = [dev matchDevicePath:path])) { ! 139: c = tail[ 0 ]; ! 140: if( c) { ! 141: if( c == ':') { ! 142: if( firstArg) ! 143: *firstArg = tail + 1; ! 144: } else ! 145: dev = nil; ! 146: } ! 147: } else ! 148: dev = nil; ! 149: ! 150: } while( (dev == nil) && (err != IO_R_NO_DEVICE)); ! 151: ! 152: return( dev); ! 153: } ! 154: ! 155: setconf() ! 156: { ! 157: int devmajor, devminor; ! 158: int unit = 0; ! 159: int slice = 0; ! 160: char * firstArg; ! 161: id dev, disk; ! 162: char * name, stringBuf[ 32 ]; ! 163: char * chosen = NULL; ! 164: char scsiName[ 10 ]; ! 165: int panelUp = 0; ! 166: BOOL sliceValid = NO; ! 167: char c; ! 168: ! 169: if( 0 == (boothowto & RB_ASKNAME)) do { ! 170: DTEntry dtEntry; ! 171: int size; ! 172: ! 173: c = rootdevice[ 0 ]; ! 174: if( c == '*') ! 175: chosen = rootdevice + 1; ! 176: if( c) ! 177: continue; ! 178: sliceValid = NO; ! 179: ! 180: if( (kSuccess == DTLookupEntry( 0, "/chosen", &dtEntry)) ! 181: && (kSuccess == DTGetProperty( dtEntry, "rootpath", (void **)&chosen, &size)) ) ! 182: continue; ! 183: ! 184: if( kSuccess != DTLookupEntry( 0, "/options", &dtEntry)) ! 185: continue; ! 186: if( kSuccess == DTGetProperty( dtEntry, "boot-file", (void **)&chosen, &size) ) ! 187: continue; ! 188: ! 189: } while( NO); ! 190: ! 191: if( chosen) { ! 192: ! 193: char * path = NULL; ! 194: enum { kPathSize = 256 }; ! 195: ! 196: path = kalloc( kPathSize ); ! 197: if( path ) { ! 198: IODealiasPath( path, chosen ); ! 199: dev = SearchForDeviceByPath( path, &firstArg ); ! 200: } else ! 201: dev = NULL; ! 202: ! 203: if( dev) { ! 204: printf("Root device for %s found: %s\n", chosen, [dev name]); ! 205: ! 206: if( sliceValid && firstArg) { ! 207: slice = strtol( firstArg, 0, 16); ! 208: if( (slice >= 8) || (slice < 0)) ! 209: slice = 0; ! 210: } ! 211: if( firstArg) { ! 212: char * tail; ! 213: extern char boot_file[]; ! 214: ! 215: // look backwards for ",kernel-name" ! 216: tail = firstArg + strlen( firstArg); ! 217: while( (tail != firstArg) && (tail[ 0 ] != ',')) ! 218: tail--; ! 219: if( tail != firstArg) { ! 220: strcpy( boot_file, tail + 1); ! 221: kprintf("Kernel name: %s\n", boot_file); ! 222: } ! 223: } ! 224: ! 225: if( [dev respondsTo:@selector(nextLogicalDisk)]) { ! 226: disk = [dev nextLogicalDisk]; ! 227: if( [disk respondsTo:@selector(waitForProbe:)]) { ! 228: if( nil == [disk waitForProbe:MAX_DISK_PROBE_TIME]) ! 229: dev = nil; ! 230: } ! 231: } ! 232: } ! 233: if( nil == dev) ! 234: boothowto |= RB_ASKNAME; ! 235: else ! 236: strcpy( rootdevice, [dev name]); ! 237: if( path) ! 238: kfree( path, kPathSize ); ! 239: } ! 240: ! 241: if ((boothowto & RB_ASKNAME) || rootdevice[0]) { ! 242: retry: ! 243: if (boothowto & RB_ASKNAME) { ! 244: ! 245: if( 0 == panelUp) { ! 246: DoSafeAlert("Root Device?", "", TRUE); ! 247: panelUp = 1; ! 248: } ! 249: safe_prf("root device? "); ! 250: name = stringBuf; ! 251: our_gets(name, name); ! 252: if (*name == 0) { ! 253: safe_prf("defaulting to en0\n"); ! 254: strcpy(name, "en0"); ! 255: } ! 256: strcpy(rootdevice, name); ! 257: } else { ! 258: /* ! 259: * If we've been asked for CDROM, find the ! 260: * corresponding sd device. ! 261: */ ! 262: if(!strcmp("cdrom", rootdevice)) { ! 263: id scsiId = nil; ! 264: int i; ! 265: IOReturn rtn; ! 266: unsigned char inquiryType; ! 267: ! 268: for(i=0; i<16; i++) { ! 269: sprintf(scsiName, "sd%d", i); ! 270: rtn = IOGetObjectForDeviceName(scsiName, ! 271: &scsiId); ! 272: if(rtn) { ! 273: break; // no more sd's ! 274: } ! 275: inquiryType = [scsiId inquiryDeviceType]; ! 276: if(inquiryType == DEVTYPE_CDROM) { ! 277: name = scsiName; ! 278: goto name_found; ! 279: } ! 280: /* else continue to next sd */ ! 281: } ! 282: if (scsiControllerDetected()) ! 283: printf("No CD-ROM drive found\n"); ! 284: else ! 285: printf("No SCSI controller or CD-ROM drive found\n"); ! 286: goto bad; ! 287: } ! 288: else { ! 289: name = rootdevice; ! 290: } ! 291: name_found: ! 292: printf ("root on %s\n", name); ! 293: } ! 294: for (gc = genericconf; gc->gc_name; gc++) ! 295: if (gc->gc_name[0] == name[0] && ! 296: gc->gc_name[1] == name[1]) ! 297: goto gotit; ! 298: goto bad; ! 299: ! 300: gotit: ! 301: if (gc->gc_root == NODEV) { ! 302: goto found; ! 303: } ! 304: if (name[2] >= '0' && name[2] <= '7') { ! 305: if (name[3] >= 'a' && name[3] <= 'h') { ! 306: slice = name[3] - 'a'; ! 307: } else if (name[3]) { ! 308: printf("bad partition number\n"); ! 309: goto bad; ! 310: } ! 311: unit = name[2] - '0'; ! 312: goto found; ! 313: } ! 314: printf("bad/missing unit number\n"); ! 315: bad: ! 316: for (gc = genericconf; gc->gc_name; gc++) ! 317: printf("%s%s%%d", ! 318: (gc == genericconf)?"use ": ! 319: (((gc+1)->gc_name)?", ":" or "), ! 320: gc->gc_name); ! 321: printf("\n"); ! 322: boothowto |= RB_ASKNAME; ! 323: goto retry; ! 324: found: ! 325: if (gc->gc_root == NODEV) { ! 326: printf("mounting nfs root\n"); ! 327: nfsbootdevname = rootdevice; ! 328: mountroot = nfs_mountroot; ! 329: rootdev = NODEV; ! 330: } else { ! 331: mountroot = ffs_mountroot; ! 332: gc->gc_root = makedev(major(gc->gc_root), unit*8+slice); ! 333: rootdev = gc->gc_root; ! 334: } ! 335: } ! 336: else ! 337: { ! 338: #ifdef BOOT_ARGS_PASSED ! 339: ! 340: boottype = kernBootStruct->rootdev; ! 341: devmajor = (boottype >> B_TYPESHIFT) & B_TYPEMASK; ! 342: devminor = (boottype >> B_PARTITIONSHIFT) & B_PARTITIONMASK; ! 343: devminor |= (((boottype >> B_UNITSHIFT) & B_UNITMASK) << 3); ! 344: ! 345: rootdev = makedev(devmajor, devminor); ! 346: #else ! 347: #if 0 ! 348: printf("mounting nfs root\n"); ! 349: if (!rootdevice[0]) ! 350: strcpy(rootdevice, "en0"); ! 351: nfsbootdevname = rootdevice; ! 352: mountroot = nfs_mountroot; ! 353: rootdev = NODEV; ! 354: #else ! 355: boothowto |= RB_ASKNAME; ! 356: goto retry; ! 357: #endif ! 358: #endif ! 359: } ! 360: printf("rootdev %x, howto %x\n", rootdev, boothowto); ! 361: ! 362: if( panelUp) ! 363: alert_done(); ! 364: } ! 365: ! 366: our_gets(cp, lp) ! 367: char *cp, *lp; ! 368: { ! 369: register c; ! 370: ! 371: for (;;) { ! 372: c = cngetc() & 0177; ! 373: switch (c) { ! 374: case '\n': ! 375: case '\r': ! 376: *lp++ = '\0'; ! 377: return; ! 378: case '\177': ! 379: if (lp == cp) { ! 380: cnputc('\b'); ! 381: continue; ! 382: } ! 383: cnputc('\b'); ! 384: cnputc('\b'); ! 385: /* fall into ... */ ! 386: case '\b': ! 387: if (lp == cp) { ! 388: cnputc('\b'); ! 389: continue; ! 390: } ! 391: cnputc(' '); ! 392: cnputc('\b'); ! 393: lp--; ! 394: continue; ! 395: case '@': ! 396: case 'u'&037: ! 397: lp = cp; ! 398: cnputc('\n'); ! 399: continue; ! 400: default: ! 401: *lp++ = c; ! 402: } ! 403: } ! 404: } ! 405: ! 406: /* ! 407: * If booted with ASKNAME, prompt on the console for a filesystem ! 408: * name and return it. ! 409: */ ! 410: getfsname(askfor, name) ! 411: char *askfor; ! 412: char *name; ! 413: { ! 414: ! 415: if (boothowto & RB_ASKNAME) { ! 416: printf("%s key [%s]: ", askfor, askfor); ! 417: our_gets(name, name); ! 418: } ! 419: } ! 420: ! 421: static int ! 422: scsiControllerDetected(void) ! 423: { ! 424: IOReturn rtn; ! 425: IOObjectNumber i; ! 426: IOString name, kind; ! 427: Protocol **protos; ! 428: id deviceId; ! 429: int j; ! 430: ! 431: protos = [SCSIDisk requiredProtocols]; ! 432: if (protos == NULL || *protos == nil) { ! 433: /* ! 434: * We can't search for a SCSI adapter, ! 435: * so don't say we didn't find one. ! 436: */ ! 437: return 1; ! 438: } ! 439: for(i = 0; ; i++) { ! 440: rtn = [IODevice lookupByObjectNumber:i deviceKind:&kind ! 441: deviceName:&name]; ! 442: if (rtn != IO_R_SUCCESS && rtn != IO_R_OFFLINE) ! 443: break; ! 444: rtn = IOGetObjectForDeviceName(name, &deviceId); ! 445: if (rtn == IO_R_SUCCESS) { ! 446: int conforms = 1; ! 447: /* Check to see if it implements the correct protocols. */ ! 448: for(j=0; protos[j]; j++) { ! 449: if(![deviceId conformsTo:protos[j]]) { ! 450: conforms = 0; ! 451: break; ! 452: } ! 453: } ! 454: if (conforms) ! 455: return 1; ! 456: } ! 457: } ! 458: return 0; ! 459: } ! 460: ! 461: bsd_autoconf() ! 462: { ! 463: #if GDB ! 464: if (IsPowerSurge()) ! 465: mace_init(); ! 466: #endif ! 467: } ! 468:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.