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