home *** CD-ROM | disk | FTP | other *** search
- /*
- * Mach Operating System
- * Copyright (c) 1992 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
- /*
- * HISTORY
- * $Log: setroot.c,v $
- * Revision 2.9 92/04/01 19:36:20 rpd
- * Changed to use machine-independent safe_gets.
- * [92/03/31 rpd]
- *
- * Revision 2.8 91/07/31 18:14:33 dbg
- * Move root_name string out of text segment for ANSI C.
- * [91/07/23 dbg]
- *
- * Revision 2.7 91/06/19 15:47:14 rvb
- * gets() must be static to not conflict with kern/printf:gets()
- *
- * Revision 2.6 90/08/27 22:12:02 dbg
- * Don't need to pass NOSYNC to boot().
- * [90/08/14 dbg]
- *
- * Revision 2.5 89/11/29 14:16:39 af
- * Made set_root a pointer rather than an array so that it can be
- * changed more easily.
- * [89/10/28 16:25:49 af]
- *
- * Revision 2.4 89/09/08 11:27:34 dbg
- * Turn on console input around gets().
- * [89/09/06 dbg]
- *
- * Revision 2.3 89/08/04 13:15:46 rwd
- * Fixed history
- *
- *
- * Revision 2.2 89/08/04 13:14:03 rwd
- * removed ip device
- *
- */
- #include <sys/types.h>
- #include <sys/reboot.h>
- #include <machine/cpu.h>
- #include <sundev/mbvar.h>
- #include <mon/sunromvec.h>
- #include <device/conf.h>
- #include <device/io_req.h>
-
- /*
- * Generic configuration; all in one
- */
- dev_t rootdev;
-
- static char devname[][2] = {
- 0,0, /* 0 = ip */
- 0,0, /* 1 = tm */
- 0,0, /* 2 = ar */
- 0,0, /* 3 = xy */
- 0,0, /* 4 = sw */
- 0,0, /* 5 = nd */
- 0,0,
- 's','d', /* 7 = sd */
- 0,0, /* 8 = xt */
- 0,0 /* 9 = sf */
- };
-
- #include <xy.h>
- #if NXY > 0
- extern struct mb_driver xycdriver;
- #endif
-
- #include <sc.h>
- #if NSC > 0
- extern struct mb_driver scdriver;
- #endif
-
- #include <si.h>
- #if NSI > 0
- extern struct mb_driver sidriver;
- #endif
-
- struct genericconf {
- char *gc_name;
- struct mb_driver *gc_driver;
- dev_t gc_root;
- } genericconf[] = {
- #if NXY > 0
- "xy", &xycdriver, makedev(3, 0),
- #endif
- #if NSC > 0
- "sd", &scdriver, makedev(7, 0),
- #endif
- #if NSI > 0
- "sd", &sidriver, makedev(7, 0),
- #endif
- #define NND 0
- #if NND > 0
- "nd", 0, makedev(5, 0),
- #endif
- 0,
- };
-
- #define PARTITIONMASK 0x7
- #define PARTITIONSHIFT 3
-
- setconf()
- {
- register struct mb_device *md;
- register struct genericconf *gc;
- int unit,swaponroot = 0;
-
- if (boothowto & RB_ASKNAME) {
- char name[128];
- retry:
- printf("root device? ");
- cnpollc(TRUE);
- safe_gets(name, sizeof name);
- cnpollc(FALSE);
- for (gc = genericconf; gc->gc_name; gc++)
- if (gc->gc_name[0] == name[0] &&
- gc->gc_name[1] == name[1])
- goto gotit;
- goto bad;
- gotit:
- if (name[3] == '*') {
- name[3] = name[4];
- swaponroot++;
- }
- if (name[2] >= '0' && name[2] <= '7' && name[3] == 0) {
- unit = name[2] - '0';
- goto found;
- }
- printf("bad/missing unit number\n");
- bad:
- printf("use one of: ");
- for (gc = genericconf; gc->gc_name; gc++)
- printf("%s%%d ", gc->gc_name);
- printf("\n");
- goto retry;
- }
- unit = 0;
- for (gc = genericconf; gc->gc_name; gc++) {
- register struct bootparam *bp = (*sunromp->v_bootparam);
-
- if (!((*gc->gc_name == bp->bp_dev[0]) &&
- (*(gc->gc_name+1) == bp->bp_dev[1])))
- continue;
- if (chkroot(gc)) {
- printf("root on %s0\n", gc->gc_name);
- goto found;
- }
- }
-
- for (gc = genericconf; gc->gc_name; gc++) {
- if (gc->gc_driver == 0) {
- /* nd is last entry in table, just try it */
- printf("root on %s0\n", gc->gc_name);
- goto found;
- }
- if (chkroot(gc)) {
- printf("root on %s0\n", gc->gc_name);
- goto found;
- }
- }
- printf("no suitable root\n");
- boot(0, RB_HALT);
- /* NOTREACHED */
-
- found:
- gc->gc_root = makedev(major(gc->gc_root), unit*8);
- rootdev = gc->gc_root;
- if (swaponroot)
- rootdev = makedev(major(rootdev), minor(rootdev)+1);
-
- }
- chkroot(gc)
- register struct genericconf *gc;
- {
- register struct mb_device *md;
- dev_ops_t ops;
- int unit;
-
- for (md = mbdinit; md->md_driver; md++) {
- if (md->md_alive == 0)
- continue;
- if (md->md_unit == 0 && md->md_driver == gc->gc_driver) {
- if (dev_name_lookup(gc->gc_name,&ops,&unit)) {
- if ((*(ops->d_open))(unit, IO_READ) == 0) {
- (void)(*(ops->d_close))(unit, IO_READ);
- return (1);
- }
- }
- }
- }
- return (0);
- }
-
- char root_name_string[16] = "\0\0\0\0\0\0\0"; /* at least ddNNp */
- char *root_name = root_name_string;
-
- get_root_device()
- {
- register int root_major, root_minor;
-
- setconf();
-
- /*
- * Now, translate device name back into string.
- */
- root_major = major(rootdev);
- root_minor = minor(rootdev);
-
- root_name[0] = devname[root_major][0];
- root_name[1] = devname[root_major][1];
- root_name[2] = '0' + (root_minor >> PARTITIONSHIFT);
- root_name[3] = 'a' + (root_minor & PARTITIONMASK);
- root_name[4] = '\0';
- }
-