Annotation of src/sys/arch/i386/i386/autoconf.c, Revision 1.7.2.5
1.1 cgd 1: /*
2: * Setup the system to run on the current machine.
3: *
4: * Configure() is called at boot time and initializes the vba
5: * device tables and the memory controller monitoring. Available
6: * devices are determined (from possibilities mentioned in ioconf.c),
7: * and the drivers are initialized.
8: */
1.7.2.2 mycroft 9: #include <sys/param.h>
10: #include <sys/buf.h>
11: #include <sys/disklabel.h>
12: #include <sys/device.h>
13: #include <sys/disk.h>
14: #include <sys/dkstat.h>
15: #include <sys/conf.h>
16: #include <sys/dmap.h>
17: #include <sys/reboot.h>
18: #include <sys/systm.h>
19:
20: void setroot __P((void));
21: static int getstr __P((char *, int));
22: static int findblkmajor __P((struct dkdevice *));
23: static struct device *getdisk __P((char *, int, int, dev_t *));
24: static struct device *parsedisk __P((char *, int, int, dev_t *));
1.1 cgd 25:
26: /*
27: * The following several variables are related to
28: * the configuration process, and are used in initializing
29: * the machine.
30: */
1.7.2.1 mycroft 31: int cold; /* if 1, still working on cold start */
1.1 cgd 32: int dkn; /* number of iostat dk numbers assigned so far */
33:
1.7.2.1 mycroft 34: void
1.1 cgd 35: configure()
36: {
1.7.2.2 mycroft 37: if (!config_rootfound("isa", NULL))
38: panic("configure: no root");
39: splnone();
40: cold = 0;
1.1 cgd 41: }
42:
43: /*
44: * Configure swap space and related parameters.
45: */
46: swapconf()
47: {
48: register struct swdevt *swp;
49: register int nblks;
50:
1.7.2.1 mycroft 51: for (swp = swdevt; swp->sw_dev != NODEV; swp++)
52: if (bdevsw[major(swp->sw_dev)].d_psize) {
53: nblks =
54: (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
55: if (nblks != -1 &&
1.1 cgd 56: (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
57: swp->sw_nblks = nblks;
58: }
59: }
60:
61: #define DOSWAP /* change swdevt and dumpdev */
1.7.2.2 mycroft 62: u_long bootdev; /* should be dev_t, but not until 32 bits */
63: struct device *bootdv;
1.1 cgd 64:
65: #define PARTITIONMASK 0x7
66: #define PARTITIONSHIFT 3
67:
1.7.2.2 mycroft 68: static int
69: findblkmajor(dv)
70: register struct dkdevice *dv;
71: {
72: register int i;
73:
74: for (i = 0; i < nblkdev; ++i)
75: if ((void (*)(struct buf *))bdevsw[i].d_strategy ==
76: dv->dk_driver->d_strategy)
77: return i;
78: return -1;
79: }
80:
81: static struct device *
82: getdisk(str, len, defpart, devp)
83: char *str;
84: int len, defpart;
85: dev_t *devp;
86: {
87: register struct device *dv;
88:
89: if ((dv = parsedisk(str, len, defpart, devp)) == NULL) {
90: printf("use one of:");
91: for (dv = alldevs; dv != NULL; dv = dv->dv_next)
92: if (dv->dv_class == DV_DISK)
93: printf(" %s[a-h]", dv->dv_xname);
94: printf("\n");
95: }
96: return dv;
97: }
98:
99: static struct device *
100: parsedisk(str, len, defpart, devp)
101: char *str;
102: int len, defpart;
103: dev_t *devp;
104: {
105: register struct device *dv;
106: register char *cp;
107: int majdev, mindev, part;
108:
109: if (len == 0)
110: return (NULL);
111: cp = str + len - 1;
112: if (*cp >= 'a' && *cp <= 'h') {
113: part = *cp - 'a';
114: *cp-- = '\0';
115: } else
116: part = defpart;
117:
118: for (dv = alldevs; dv != NULL; dv = dv->dv_next)
119: if (dv->dv_class == DV_DISK &&
120: strcmp(str, dv->dv_xname) == 0) {
121: majdev = findblkmajor((struct dkdevice *)dv);
122: if (majdev < 0)
123: panic("parsedisk");
124: mindev = (dv->dv_unit << PARTITIONSHIFT) + part;
125: *devp = makedev(majdev, mindev);
126: return (dv);
127: }
128:
129: return (NULL);
130: }
131:
1.1 cgd 132: /*
133: * Attempt to find the device from which we were booted.
134: * If we can do so, and not instructed not to do so,
135: * change rootdev to correspond to the load device.
136: */
1.7.2.2 mycroft 137: void
1.1 cgd 138: setroot()
139: {
1.7.2.2 mycroft 140: register struct swdevt *swp;
141: register struct device *dv;
142: register int len, majdev, mindev, part;
143: dev_t nrootdev, nswapdev;
144: char buf[128];
145: #ifdef DOSWAP
146: dev_t temp;
147: #endif
1.7.2.3 mycroft 148: #ifdef NFSCLIENT
1.7.2.2 mycroft 149: extern int (*mountroot)(), nfs_mountroot();
150: #endif
151:
152: if (boothowto & RB_ASKNAME) {
153: for (;;) {
1.7.2.4 mycroft 154: printf("root device");
155: if (bootdv)
156: printf(" (default %s%c)", bootdv->dv_xname,
157: (minor(bootdev) & PARTITIONMASK) + 'a');
158: printf("? ");
1.7.2.2 mycroft 159: len = getstr(buf, sizeof(buf));
1.7.2.4 mycroft 160: if (bootdv && len == 0) {
161: nrootdev = bootdev;
162: break;
163: }
1.7.2.2 mycroft 164: #ifdef GENERIC
165: if (len > 0 && buf[len - 1] == '*') {
166: buf[--len] = '\0';
167: dv = getdisk(buf, len, 1, &nrootdev);
168: if (dv != NULL) {
169: bootdv = dv;
170: nswapdev = nrootdev;
171: goto gotswap;
172: }
173: }
174: #endif
175: dv = getdisk(buf, len, 0, &nrootdev);
176: if (dv != NULL) {
177: bootdv = dv;
178: break;
179: }
180: }
181: for (;;) {
182: printf("swap device (default %sb)? ", bootdv->dv_xname);
183: len = getstr(buf, sizeof(buf));
184: if (len == 0) {
185: nswapdev = makedev(major(nrootdev),
186: (minor(nrootdev) & ~ PARTITIONMASK) | 1);
187: break;
188: }
189: if (getdisk(buf, len, 1, &nswapdev) != NULL)
190: break;
191: }
192: #ifdef GENERIC
193: gotswap:
194: #endif
195: rootdev = nrootdev;
196: swapdev = nswapdev;
197: dumpdev = nswapdev; /* ??? */
198: swdevt[0].sw_dev = nswapdev;
199: swdevt[1].sw_dev = NODEV;
200: return;
201: }
202:
203: /* XXX currently there's no way to set RB_DFLTROOT... */
204: if (boothowto & RB_DFLTROOT || bootdv == NULL)
205: return;
206:
207: switch (bootdv->dv_class) {
208:
1.7.2.3 mycroft 209: #ifdef NFSCLIENT
1.7.2.2 mycroft 210: case DV_IFNET:
211: mountroot = nfs_mountroot;
212: return;
213: #endif
214:
215: #if defined(FFS) || defined(LFS)
216: case DV_DISK:
217: majdev = findblkmajor((struct dkdevice *)bootdv);
218: if (majdev < 0)
219: return;
220: part = 0;
221: mindev = (bootdv->dv_unit << PARTITIONSHIFT) + part;
222: break;
223: #endif
224:
225: default:
226: printf("can't figure root, hope your kernel is right\n");
227: return;
228: }
229:
1.1 cgd 230: /*
1.7.2.2 mycroft 231: * Form a new rootdev
232: */
233: nrootdev = makedev(majdev, mindev);
234: /*
1.1 cgd 235: * If the original rootdev is the same as the one
236: * just calculated, don't need to adjust the swap configuration.
237: */
1.7.2.2 mycroft 238: if (rootdev == nrootdev)
1.1 cgd 239: return;
1.7.2.2 mycroft 240:
241: rootdev = nrootdev;
242: printf("Changing root device to %s%c\n", bootdv->dv_xname, part + 'a');
243:
1.1 cgd 244: #ifdef DOSWAP
245: mindev &= ~PARTITIONMASK;
1.7.2.2 mycroft 246: temp = NODEV;
247: for (swp = swdevt; swp->sw_dev != NODEV; swp++) {
1.1 cgd 248: if (majdev == major(swp->sw_dev) &&
249: mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
250: temp = swdevt[0].sw_dev;
251: swdevt[0].sw_dev = swp->sw_dev;
252: swp->sw_dev = temp;
253: break;
254: }
255: }
1.7.2.2 mycroft 256: if (swp->sw_dev == NODEV)
1.1 cgd 257: return;
1.7.2.2 mycroft 258:
1.1 cgd 259: /*
1.7.2.2 mycroft 260: * If dumpdev was the same as the old primary swap device, move
261: * it to the new primary swap device.
1.1 cgd 262: */
263: if (temp == dumpdev)
264: dumpdev = swdevt[0].sw_dev;
265: #endif
1.7.2.2 mycroft 266: }
267:
268: static int
269: getstr(cp, size)
270: register char *cp;
271: register int size;
272: {
273: register char *lp;
274: register int c;
275: register int len;
276:
277: lp = cp;
278: len = 0;
279: for (;;) {
280: c = cngetc();
281: switch (c) {
282: case '\n':
283: case '\r':
284: printf("\n");
285: *lp++ = '\0';
286: return (len);
287: case '\b':
288: case '\177':
289: case '#':
290: if (len) {
291: --len;
292: --lp;
293: printf("\b \b");
294: }
295: continue;
296: case '@':
297: case 'u'&037:
298: len = 0;
299: lp = cp;
300: printf("\n");
301: continue;
302: default:
303: if (len + 1 >= size || c < ' ') {
304: printf("\007");
305: continue;
306: }
307: printf("%c", c);
308: ++len;
309: *lp++ = c;
310: }
311: }
1.1 cgd 312: }
CVSweb <webmaster@jp.NetBSD.org>