[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

New i386 rootdev diffs...



Hello all.

I've got some diffs that I need tested.  People that have been having trouble
with the kernel trying to mount the wrong partition as the root device may be
happy to receive these diffs.  They should fix all known (at least to me)
problems with the kernel messing up on mounting the root device.

The diff attached (also at http://natasha.powersurfr.com/~weingart/OpenBSD/
in the file rootdev-1.diff in case it gets trashed in the mail), does some
cleanup (more needed) of the code, removes i386 dependant code from init_main.c
and gives a way for other architectures to do the same sort of thing that
we need to do on the i386.

To find and match-up the bios drive numbers to the bsd devices, we first make
a good guess, and then refine that guess when we run the disk-checksum stuff
in the kernel, using the checksums to update things as we go along.  I figure
that as long as the checksum stuff works, this should work fine.  Please,
report all problems to me, I'd like to get this diff out of my tree quickly.

--Toby.

Index: arch/i386/i386/autoconf.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/autoconf.c,v
retrieving revision 1.29
diff -u -r1.29 autoconf.c
--- arch/i386/i386/autoconf.c	1999/07/30 19:05:09	1.29
+++ arch/i386/i386/autoconf.c	1999/08/26 01:42:34
@@ -62,9 +62,10 @@
 
 #include <dev/cons.h>
 
+void rootconf __P((void));
 void swapconf __P((void));
 void setroot __P((void));
-void setconf __P((void));
+void diskconf __P((void));
 
 /*
  * The following several variables are related to
@@ -72,6 +73,7 @@
  * the machine.
  */
 extern int	cold;		/* cold start flag initialized in locore.s */
+dev_t	bootdev = 0;		/* bootdevice, initialized in locore.s */
 
 /*
  * Determine i/o configuration for a machine.
@@ -91,15 +93,34 @@
 
 	spl0();
 
-	setconf();
+	/*
+	 * We can not know which is our root disk, defer
+	 * until we can checksum blocks to figure it out.
+	 */
+	md_diskconf = diskconf;
+	cold = 0;
+}
 
+/*
+ * Now that we are fully operational, we can checksum the
+ * disks, and using some heuristics, hopefully are able to
+ * always determine the correct root disk.
+ */
+void
+diskconf()
+{
 	/*
-	 * Configure swap area and related system
-	 * parameter based on device(s) used.
+	 * Configure root, swap, and dump area.  This is
+	 * currently done by running the same checksum
+	 * algorithm over all known disks, as was done in
+	 * /boot.  Then we basically fixup the *dev vars
+	 * from the info we gleaned from this.
 	 */
+	dkcsumattach();
+
+	rootconf();
 	swapconf();
 	dumpconf();
-	cold = 0;
 }
 
 /*
@@ -127,7 +148,6 @@
 }
 
 #define	DOSWAP			/* change swdevt and dumpdev */
-u_long	bootdev = 0;		/* should be dev_t, but not until 32 bits */
 
 static const char *devname[] = {
 	"wd",		/* 0 = wd */
@@ -176,13 +196,13 @@
 	if (boothowto & RB_DFLTROOT ||
 	    (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
 		return;
-	majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
+	majdev = B_TYPE(bootdev);
 	if (majdev > sizeof(devname)/sizeof(devname[0]) ||
 	    *devname[majdev] == '\0')
 		return;
-	adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
-	part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
-	unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
+	adaptor = B_ADAPTOR(bootdev);
+	part = B_PARTITION(bootdev);
+	unit = B_UNIT(bootdev);
 	mindev = (unit * MAXPARTITIONS) + part;
 	orootdev = rootdev;
 	rootdev = makedev(majdev, mindev);
@@ -268,17 +288,14 @@
 };
 
 void
-setconf()
+rootconf()
 {
 	register struct genericconf *gc;
 	int unit, part = 0;
-#if 0
-	int swaponroot = 0;
-#endif
 	char *num;
 
 #ifdef INSTALL
-	if (((bootdev >> B_TYPESHIFT) & B_TYPEMASK) == 2) {
+	if (B_TYPE(bootdev) == 2) {
 		printf("\n\nInsert file system floppy...\n");
 		if (!(boothowto & RB_ASKNAME))
 			cngetc();
@@ -299,12 +316,6 @@
 				break;
 		if (gc->gc_driver) {
 			num = &name[strlen(gc->gc_name)];
-#if 0
-			if (num[0] == '*') {
-				strcpy(num, num+1);
-				swaponroot++;
-			}
-#endif
 
 			unit = -2;
 			do {
@@ -360,8 +371,4 @@
 	swdevt[0].sw_dev = argdev = dumpdev =
 	    makedev(major(rootdev), minor(rootdev) + 1);
 	/* swap size and dumplo set during autoconfigure */
-#if 0
-	if (swaponroot)
-		rootdev = dumpdev;
-#endif
 }
Index: arch/i386/i386/dkcsum.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/dkcsum.c,v
retrieving revision 1.8
diff -u -r1.8 dkcsum.c
--- arch/i386/i386/dkcsum.c	1999/07/24 23:04:34	1.8
+++ arch/i386/i386/dkcsum.c	1999/08/26 01:42:34
@@ -55,9 +55,8 @@
 
 extern u_int32_t bios_cksumlen;
 extern bios_diskinfo_t *bios_diskinfo;
+extern dev_t bootdev;
 
-void dkcsumattach __P((void));			/* XXX should be elsewhere */
-
 void
 dkcsumattach()
 {
@@ -167,6 +166,24 @@
 			    dv->dv_xname);
 #endif
 			continue;
+		}
+
+		/* Fixup bootdev if units match.  This means that all of
+		 * hd*, sd*, wd*, will be interpreted the same.  Not 100%
+		 * backwards compatible, but sd* and wd* should be phased-
+		 * out in the bootblocks.
+		 */
+		if (B_UNIT(bootdev) == (hit->bios_number & 0x7F)) {
+			int type, ctrl, adap, part, unit;
+
+			/* Translate to MAKEBOOTDEV() style */
+			type = major(bp->b_dev);
+			adap = B_ADAPTOR(bootdev);
+			ctrl = B_CONTROLLER(bootdev);
+			unit = DISKUNIT(bp->b_dev);
+			part = B_PARTITION(bootdev);
+
+			bootdev = MAKEBOOTDEV(type, ctrl, adap, unit, part);
 		}
 
 		/* This will overwrite /boot's guess, just so you remember */
Index: arch/i386/include/cpu.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/cpu.h,v
retrieving revision 1.27
diff -u -r1.27 cpu.h
--- arch/i386/include/cpu.h	1999/07/06 07:59:54	1.27
+++ arch/i386/include/cpu.h	1999/08/26 01:42:34
@@ -175,6 +175,9 @@
 /* autoconf.c */
 void	configure __P((void));
 
+/* dkcsum.c */
+void	dkcsumattach __P((void));
+
 /* machdep.c */
 void	delay __P((int));
 void	dumpconf __P((void));
Index: kern/init_main.c
===================================================================
RCS file: /cvs/src/sys/kern/init_main.c,v
retrieving revision 1.40
diff -u -r1.40 init_main.c
--- kern/init_main.c	1999/08/17 10:32:18	1.40
+++ kern/init_main.c	1999/08/26 01:42:47
@@ -123,6 +123,7 @@
 int	cmask = CMASK;
 extern	struct user *proc0paddr;
 
+void	(*md_diskconf) __P((void)) = NULL;
 struct	vnode *rootvp, *swapdev_vp;
 int	boothowto;
 struct	timeval boottime;
@@ -364,16 +365,9 @@
 	roundrobin(NULL);
 	schedcpu(NULL);
 
-#ifdef i386
-#include "bios.h"
-#if NBIOS
-	/* XXX This is only a transient solution */
-	{
-		extern void dkcsumattach __P((void));
-		dkcsumattach();
-	}
-#endif
-#endif
+	/* Configure root/swap devices */
+	if (md_diskconf)
+		(*md_diskconf)();
 
 	/* Mount the root file system. */
 	if (vfs_mountroot())
Index: sys/systm.h
===================================================================
RCS file: /cvs/src/sys/sys/systm.h,v
retrieving revision 1.31
diff -u -r1.31 systm.h
--- sys/systm.h	1999/07/21 21:12:51	1.31
+++ sys/systm.h	1999/08/26 01:42:50
@@ -246,6 +246,7 @@
 
 void	cpu_startup __P((void));
 void	cpu_set_kpc __P((struct proc *, void (*)(void *), void *));
+extern void (*md_diskconf) __P((void));
 
 
 #ifdef GPROF





Visit your host, monkey.org