|
|
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.