When booting an i386 kernel with Multiboot, properly detect the boot device trunk
authorjmmv <jmmv@NetBSD.org>
Fri, 03 Feb 2006 23:33:30 +0000
branchtrunk
changeset 143149 8bf4025b7877
parent 143148 c8505dfb2c40
child 143150 e7a9ab8731ce
child 288378 5d801722484c
When booting an i386 kernel with Multiboot, properly detect the boot device by looking it up in the x86_alldisks table (instead of trying to match it to 'wd*' manually). In order to do this, move the cpu_rootconf function from x86 common code to amd64 and i386 specific one. This way, i386 can do an extra step (call the appropriate Multiboot code) in the appropriate place (after x86_matchbiosdisks and before findroot()).
distrib/sets/lists/comp/md.amd64
distrib/sets/lists/comp/md.i386
sys/arch/amd64/amd64/autoconf.c
sys/arch/amd64/include/Makefile
sys/arch/amd64/include/autoconf.h
sys/arch/i386/i386/autoconf.c
sys/arch/i386/i386/multiboot.c
sys/arch/i386/include/Makefile
sys/arch/i386/include/autoconf.h
sys/arch/i386/include/multiboot.h
sys/arch/x86/include/Makefile
sys/arch/x86/include/autoconf.h
sys/arch/x86/x86/x86_autoconf.c
--- a/distrib/sets/lists/comp/md.amd64	Fri Feb 03 22:50:21 2006 +0000
+++ b/distrib/sets/lists/comp/md.amd64	Fri Feb 03 23:33:30 2006 +0000
@@ -1,9 +1,10 @@
-# $NetBSD: md.amd64,v 1.17 2005/01/21 04:47:23 dyoung Exp $
+# $NetBSD: md.amd64,v 1.18 2006/02/03 23:33:30 jmmv Exp $
 ./usr/include/amd64				comp-c-include
 ./usr/include/amd64/ansi.h			comp-c-include
 ./usr/include/amd64/aout_machdep.h		comp-c-include
 ./usr/include/amd64/asm.h			comp-c-include
 ./usr/include/amd64/atomic.h			comp-c-include
+./usr/include/amd64/autoconf.h			comp-c-include
 ./usr/include/amd64/bootinfo.h			comp-c-include
 ./usr/include/amd64/bswap.h			comp-c-include
 ./usr/include/amd64/bus.h			comp-c-include
@@ -125,6 +126,7 @@
 ./usr/include/x64_64/vmparam.h			comp-obsolete		obsolete
 ./usr/include/x86				comp-c-include
 ./usr/include/x86/aout_machdep.h		comp-c-include
+./usr/include/x86/autoconf.h			comp-c-include
 ./usr/include/x86/bootinfo.h			comp-c-include
 ./usr/include/x86/bus.h				comp-c-include
 ./usr/include/x86/cacheinfo.h			comp-c-include
--- a/distrib/sets/lists/comp/md.i386	Fri Feb 03 22:50:21 2006 +0000
+++ b/distrib/sets/lists/comp/md.i386	Fri Feb 03 23:33:30 2006 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: md.i386,v 1.88 2006/02/03 11:08:23 jmmv Exp $
+# $NetBSD: md.i386,v 1.89 2006/02/03 23:33:30 jmmv Exp $
 ./usr/include/emmintrin.h			comp-c-include		gcccmds
 ./usr/include/i386				comp-c-include
 ./usr/include/i386/_G_config.h			comp-obsolete		obsolete
@@ -7,6 +7,7 @@
 ./usr/include/i386/apmvar.h			comp-c-include
 ./usr/include/i386/asm.h			comp-c-include
 ./usr/include/i386/atomic.h			comp-c-include
+./usr/include/i386/autoconf.h			comp-c-include
 ./usr/include/i386/bioscall.h			comp-c-include
 ./usr/include/i386/bootinfo.h			comp-c-include
 ./usr/include/i386/bswap.h			comp-c-include
@@ -79,6 +80,7 @@
 ./usr/include/pmc.h				comp-c-include
 ./usr/include/x86				comp-c-include
 ./usr/include/x86/aout_machdep.h		comp-c-include
+./usr/include/x86/autoconf.h			comp-c-include
 ./usr/include/x86/bootinfo.h			comp-c-include
 ./usr/include/x86/bus.h				comp-c-include
 ./usr/include/x86/cacheinfo.h			comp-c-include
--- a/sys/arch/amd64/amd64/autoconf.c	Fri Feb 03 22:50:21 2006 +0000
+++ b/sys/arch/amd64/amd64/autoconf.c	Fri Feb 03 23:33:30 2006 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: autoconf.c,v 1.12 2005/12/11 12:16:21 christos Exp $	*/
+/*	$NetBSD: autoconf.c,v 1.13 2006/02/03 23:33:31 jmmv Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.12 2005/12/11 12:16:21 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.13 2006/02/03 23:33:31 jmmv Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -54,6 +54,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 
+#include <machine/autoconf.h>
 #include <machine/pte.h>
 #include <machine/cpu.h>
 
@@ -107,3 +108,12 @@
 	spl0();
 	lcr8(0);
 }
+
+void
+cpu_rootconf(void)
+{
+
+	x86_matchbiosdisks();
+
+	x86_cpu_rootconf();
+}
--- a/sys/arch/amd64/include/Makefile	Fri Feb 03 22:50:21 2006 +0000
+++ b/sys/arch/amd64/include/Makefile	Fri Feb 03 23:33:30 2006 +0000
@@ -1,8 +1,8 @@
-#	$NetBSD: Makefile,v 1.4 2005/12/11 12:16:25 christos Exp $
+#	$NetBSD: Makefile,v 1.5 2006/02/03 23:33:31 jmmv Exp $
 
 INCSDIR= /usr/include/amd64
 
-INCS=	ansi.h aout_machdep.h asm.h atomic.h \
+INCS=	ansi.h aout_machdep.h autoconf.h asm.h atomic.h \
 	bootinfo.h bswap.h bus.h byte_swap.h \
 	cdefs.h cpu.h cpufunc.h \
 	disklabel.h \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/amd64/include/autoconf.h	Fri Feb 03 23:33:30 2006 +0000
@@ -0,0 +1,3 @@
+/*	$NetBSD: autoconf.h,v 1.1 2006/02/03 23:33:31 jmmv Exp $	*/
+
+#include <x86/autoconf.h>
--- a/sys/arch/i386/i386/autoconf.c	Fri Feb 03 22:50:21 2006 +0000
+++ b/sys/arch/i386/i386/autoconf.c	Fri Feb 03 23:33:30 2006 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: autoconf.c,v 1.81 2005/12/11 12:17:41 christos Exp $	*/
+/*	$NetBSD: autoconf.c,v 1.82 2006/02/03 23:33:30 jmmv Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -46,7 +46,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.81 2005/12/11 12:17:41 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.82 2006/02/03 23:33:30 jmmv Exp $");
 
 #include "opt_compat_oldboot.h"
 #include "opt_multiprocessor.h"
@@ -57,6 +57,8 @@
 #include <sys/proc.h>
 #include <sys/user.h>
 
+#include <machine/autoconf.h>
+#include <machine/multiboot.h>
 #include <machine/pte.h>
 #include <machine/cpu.h>
 #include <machine/gdt.h>
@@ -135,3 +137,16 @@
 	lapic_tpr = 0;
 #endif
 }
+
+void
+cpu_rootconf(void)
+{
+
+	x86_matchbiosdisks();
+
+#ifdef MULTIBOOT
+	multiboot_pre_findroot();
+#endif
+
+	x86_cpu_rootconf();
+}
--- a/sys/arch/i386/i386/multiboot.c	Fri Feb 03 22:50:21 2006 +0000
+++ b/sys/arch/i386/i386/multiboot.c	Fri Feb 03 23:33:30 2006 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: multiboot.c,v 1.1 2006/02/03 11:08:24 jmmv Exp $	*/
+/*	$NetBSD: multiboot.c,v 1.2 2006/02/03 23:33:30 jmmv Exp $	*/
 
 /*-
  * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: multiboot.c,v 1.1 2006/02/03 11:08:24 jmmv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: multiboot.c,v 1.2 2006/02/03 23:33:30 jmmv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -47,6 +47,7 @@
 #include <sys/exec_elf.h>
 #include <sys/optstr.h>
 
+#include <machine/autoconf.h>
 #include <machine/bootinfo.h>
 #include <machine/multiboot.h>
 
@@ -195,7 +196,6 @@
 	setup_howto(mi);
 	setup_bootpath(mi);
 	setup_biosgeom(mi);
-	setup_bootdisk(mi);
 	setup_memmap(mi);
 	setup_syms(mi);
 }
@@ -203,6 +203,28 @@
 /* --------------------------------------------------------------------- */
 
 /*
+ * Sets up the kernel if it was booted by a Multiboot-compliant boot
+ * loader.  This is executed before calling findroot() in cpu_rootconf().
+ * At this point, there is not much more to do.  We only seize this call
+ * to set up the default root device because all device drivers have
+ * already been initialized and are available for us to use.
+ */
+void
+multiboot_pre_findroot(void)
+{
+	struct multiboot_info *mi;
+	
+	if (! Multiboot_Loader)
+		return;
+
+	mi = &Multiboot_Info;
+
+	setup_bootdisk(mi);
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
  * Prints a summary of the information collected in the Multiboot
  * information header (if present).  Done as a separate function because
  * the console has to be available.
@@ -473,17 +495,13 @@
 	if (!found && (mi->mi_flags & MULTIBOOT_INFO_HAS_BOOT_DEVICE)) {
 		const char *devprefix;
 
-		/* XXX: This should use x86_alldisks to find the correct
-		 * match.  But, at this point, neither the drivers nor the
-		 * vector are initialized... */
-		switch (mi->mi_boot_device_drive) {
-		case 0x00:	devprefix = "fd0";	break;
-		case 0x01:	devprefix = "fd1";	break;
-		case 0x80:	devprefix = "wd0";	break;
-		case 0x81:	devprefix = "wd1";	break;
-		case 0x82:	devprefix = "wd2";	break;
-		case 0x83:	devprefix = "wd3";	break;
-		default:	devprefix = "";
+		devprefix = x86_findbiosdisk(mi->mi_boot_device_drive);
+		if (devprefix == NULL) {
+			switch (mi->mi_boot_device_drive) {
+			case 0x00:	devprefix = "fd0";	break;
+			case 0x01:	devprefix = "fd1";	break;
+			default:	devprefix = "";
+			}
 		}
 
 		if (devprefix[0] != '\0') {
--- a/sys/arch/i386/include/Makefile	Fri Feb 03 22:50:21 2006 +0000
+++ b/sys/arch/i386/include/Makefile	Fri Feb 03 23:33:30 2006 +0000
@@ -1,8 +1,8 @@
-#	$NetBSD: Makefile,v 1.30 2006/02/03 11:08:24 jmmv Exp $
+#	$NetBSD: Makefile,v 1.31 2006/02/03 23:33:30 jmmv Exp $
 
 INCSDIR= /usr/include/i386
 
-INCS=	ansi.h aout_machdep.h apmvar.h asm.h atomic.h \
+INCS=	ansi.h aout_machdep.h autoconf.h apmvar.h asm.h atomic.h \
 	bioscall.h bootinfo.h bswap.h byte_swap.h bus.h \
 	cdefs.h cpu.h cpufunc.h cputypes.h \
 	db_machdep.h disklabel.h \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/i386/include/autoconf.h	Fri Feb 03 23:33:30 2006 +0000
@@ -0,0 +1,3 @@
+/*	$NetBSD: autoconf.h,v 1.1 2006/02/03 23:33:30 jmmv Exp $	*/
+
+#include <x86/autoconf.h>
--- a/sys/arch/i386/include/multiboot.h	Fri Feb 03 22:50:21 2006 +0000
+++ b/sys/arch/i386/include/multiboot.h	Fri Feb 03 23:33:30 2006 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: multiboot.h,v 1.1 2006/02/03 11:08:24 jmmv Exp $	*/
+/*	$NetBSD: multiboot.h,v 1.2 2006/02/03 23:33:30 jmmv Exp $	*/
 
 /*-
  * Copyright (c) 2005, 2006 The NetBSD Foundation, Inc.
@@ -208,6 +208,7 @@
 #if !defined(_LOCORE)
 void		multiboot_pre_reloc(struct multiboot_info *);
 void		multiboot_post_reloc(void);
+void		multiboot_pre_findroot(void);
 void		multiboot_print_info(void);
 #endif /* !defined(_LOCORE) */
 
--- a/sys/arch/x86/include/Makefile	Fri Feb 03 22:50:21 2006 +0000
+++ b/sys/arch/x86/include/Makefile	Fri Feb 03 23:33:30 2006 +0000
@@ -1,8 +1,8 @@
-# 	$NetBSD: Makefile,v 1.5 2003/10/22 11:54:23 kleink Exp $
+# 	$NetBSD: Makefile,v 1.6 2006/02/03 23:33:30 jmmv Exp $
 
 INCSDIR=/usr/include/x86
 
-INCS=	aout_machdep.h \
+INCS=	aout_machdep.h autoconf.h \
 	bootinfo.h bus.h \
 	cacheinfo.h \
 	cpuvar.h \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/x86/include/autoconf.h	Fri Feb 03 23:33:30 2006 +0000
@@ -0,0 +1,10 @@
+/*	$NetBSD: autoconf.h,v 1.1 2006/02/03 23:33:30 jmmv Exp $	*/
+
+#ifndef _X86_AUTOCONF_H_
+#define _X86_AUTOCONF_H_
+
+void x86_cpu_rootconf(void);
+void x86_matchbiosdisks(void);
+const char *x86_findbiosdisk(int);
+
+#endif /* _X86_AUTOCONF_H_ */
--- a/sys/arch/x86/x86/x86_autoconf.c	Fri Feb 03 22:50:21 2006 +0000
+++ b/sys/arch/x86/x86/x86_autoconf.c	Fri Feb 03 23:33:30 2006 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: x86_autoconf.c,v 1.6 2006/02/03 11:08:24 jmmv Exp $	*/
+/*	$NetBSD: x86_autoconf.c,v 1.7 2006/02/03 23:33:30 jmmv Exp $	*/
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -52,6 +52,8 @@
 #include <sys/proc.h>
 #include <sys/md5.h>
 
+#include <x86/autoconf.h>
+
 #include <machine/bootinfo.h>
 
 #include "pci.h"
@@ -82,8 +84,8 @@
  * XXX Ugly bit of code.  But, this is the only safe time that the
  * match between BIOS disks and native disks can be done.
  */
-static void
-matchbiosdisks(void)
+void
+x86_matchbiosdisks(void)
 {
 	struct btinfo_biosgeom *big;
 	struct bi_biosgeom_entry *be;
@@ -201,6 +203,35 @@
 	}
 }
 
+const char *
+x86_findbiosdisk(int devnum)
+{
+	int i;
+
+	KASSERT(x86_alldisks != NULL);
+
+	for (i = 0; i < x86_alldisks->dl_nnativedisks; i++) {
+		int j;
+		struct nativedisk_info *ni;
+
+		ni = &x86_alldisks->dl_nativedisks[i];
+
+		for (j = 0; j < ni->ni_nmatches; j++) {
+			int k;
+			struct biosdisk_info *bi;
+
+			k = ni->ni_biosmatches[j];
+			KASSERT(k < x86_alldisks->dl_nbiosdisks);
+			bi = &x86_alldisks->dl_biosdisks[k];
+
+			if (bi->bi_dev == devnum)
+				return ni->ni_devname;
+		}
+	}
+
+	return NULL;
+}
+
 /*
  * Helper function for findroot():
  * Return non-zero if wedge device matches bootinfo.
@@ -535,11 +566,10 @@
 }
 
 void
-cpu_rootconf(void)
+x86_cpu_rootconf(void)
 {
 
 	findroot();
-	matchbiosdisks();
 
 	if (booted_wedge) {
 		KASSERT(booted_device != NULL);