aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMike Smith <msmith@FreeBSD.org>1998-10-02 16:32:45 +0000
committerMike Smith <msmith@FreeBSD.org>1998-10-02 16:32:45 +0000
commit6b15efd961c80cf9986157aea1370419b6385860 (patch)
tree6b38031e2b89eb4dd97766826e30432917a293d9 /sys
parent39de38225b3e84c7c1f3ce058bf922f966fbdef9 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/boot/i386/libi386/aout_freebsd.c38
-rw-r--r--sys/boot/i386/libi386/biosdisk.c201
-rw-r--r--sys/boot/i386/libi386/comconsole.c4
-rw-r--r--sys/boot/i386/libi386/libi386.h16
-rw-r--r--sys/boot/i386/libi386/vidconsole.c4
5 files changed, 176 insertions, 87 deletions
diff --git a/sys/boot/i386/libi386/aout_freebsd.c b/sys/boot/i386/libi386/aout_freebsd.c
index dc78412316609..2f7c0885a85fd 100644
--- a/sys/boot/i386/libi386/aout_freebsd.c
+++ b/sys/boot/i386/libi386/aout_freebsd.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: aout_freebsd.c,v 1.6 1998/09/29 09:11:49 peter Exp $
+ * $Id: aout_freebsd.c,v 1.7 1998/09/30 19:42:06 peter Exp $
*/
#include <sys/param.h>
@@ -54,33 +54,45 @@ static int
aout_exec(struct loaded_module *mp)
{
struct loaded_module *xp;
- struct i386_devdesc *currdev;
+ struct i386_devdesc *rootdev;
struct module_metadata *md;
struct exec *ehdr;
u_int32_t argv[6]; /* kernel arguments */
int major, bootdevnr;
vm_offset_t addr, entry;
u_int pad;
+ char *rootdevname;
if ((md = mod_findmetadata(mp, MODINFOMD_AOUTEXEC)) == NULL)
return(EFTYPE); /* XXX actually EFUCKUP */
ehdr = (struct exec *)&(md->md_data);
+ /*
+ * Allow the environment variable 'rootdev' to override the supplied device
+ * This should perhaps go to MI code and/or have $rootdev tested/set by
+ * MI code before launching the kernel.
+ */
+ rootdevname = getenv("rootdev");
+ i386_getdev((void **)(&rootdev), rootdevname, NULL);
+ if (rootdev == NULL) { /* bad $rootdev/$currdev */
+ printf("can't determine root device\n");
+ return(EINVAL);
+ }
+
/* Boot from whatever the current device is */
- i386_getdev((void **)(&currdev), NULL, NULL);
- switch(currdev->d_type) {
- case DEVT_DISK:
- major = 0; /* XXX work out the best possible major here */
- bootdevnr = MAKEBOOTDEV(major,
- currdev->d_kind.biosdisk.slice >> 4,
- currdev->d_kind.biosdisk.slice & 0xf,
- currdev->d_kind.biosdisk.unit,
- currdev->d_kind.biosdisk.partition);
+ i386_getdev((void **)(&rootdev), NULL, NULL);
+ switch(rootdev->d_type) {
+ case DEVT_DISK:
+ /* pass in the BIOS device number of the current disk */
+ bi.bi_bios_dev = bd_unit2bios(rootdev->d_kind.biosdisk.unit);
+ bootdevnr = bd_getdev(rootdev);
break;
+
default:
- printf("aout_exec: WARNING - don't know how to boot from device type %d\n", currdev->d_type);
+ printf("aout_exec: WARNING - don't know how to boot from device type %d\n", rootdev->d_type);
}
- free(currdev);
+ free(rootdev);
+
/* legacy bootinfo structure */
bi.bi_version = BOOTINFO_VERSION;
diff --git a/sys/boot/i386/libi386/biosdisk.c b/sys/boot/i386/libi386/biosdisk.c
index e7ed4590806fe..0855368a62c3b 100644
--- a/sys/boot/i386/libi386/biosdisk.c
+++ b/sys/boot/i386/libi386/biosdisk.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: biosdisk.c,v 1.7 1998/09/28 20:07:39 peter Exp $
+ * $Id: biosdisk.c,v 1.8 1998/09/28 20:08:34 peter Exp $
*/
/*
@@ -41,6 +41,7 @@
#include <sys/disklabel.h>
#include <sys/diskslice.h>
+#include <sys/reboot.h>
#include <bootstrap.h>
#include <btxv86.h>
@@ -50,6 +51,12 @@
#define BUFSIZE (1 * BIOSDISK_SECSIZE)
#define MAXBDDEV MAXDEV
+#define DT_ATAPI 0x10 /* disk type for ATAPI floppies */
+#define WDMAJOR 0 /* major numbers for devices we frontend for */
+#define WFDMAJOR 1
+#define FDMAJOR 2
+#define DAMAJOR 4
+
#ifdef DISK_DEBUG
# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __FUNCTION__ , ## args)
#else
@@ -70,15 +77,28 @@ struct open_disk {
#define BD_MODEEDD1 0x1
#define BD_MODEEDD3 0x2
#define BD_FLOPPY (1<<2)
- u_char od_buf[BUFSIZE]; /* transfer buffer (do we want/need this?) */
+ struct disklabel od_disklabel;
+ struct dos_partition od_parttab;
+#define BD_LABELOK (1<<3)
+#define BD_PARTTABOK (1<<4)
};
+/*
+ * List of BIOS devices, translation from disk unit number to
+ * BIOS unit number.
+ */
+static struct bdinfo
+{
+ int bd_unit; /* BIOS unit number */
+ int bd_flags;
+ int bd_type; /* BIOS 'drive type' (floppy only) */
+} bdinfo [MAXBDDEV];
+static int nbdinfo = 0;
+
static int bd_getgeom(struct open_disk *od);
static int bd_read(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest);
-static int bd_edd3probe(int unit);
-static int bd_edd1probe(int unit);
-static int bd_int13probe(int unit);
+static int bd_int13probe(struct bdinfo *bd);
static int bd_init(void);
static int bd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, void *buf, size_t *rsize);
@@ -95,16 +115,30 @@ struct devsw biosdisk = {
noioctl
};
+static int bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev);
+static void bd_closedisk(struct open_disk *od);
+
/*
- * List of BIOS devices, translation from disk unit number to
- * BIOS unit number.
+ * Translate between BIOS device numbers and our private unit numbers.
*/
-static struct
+int
+bd_bios2unit(int biosdev)
{
- int bd_unit; /* BIOS unit number */
- int bd_flags;
-} bdinfo [MAXBDDEV];
-static int nbdinfo = 0;
+ int i;
+
+ for (i = 0; i < nbdinfo; i++)
+ if (bdinfo[i].bd_unit == biosdev)
+ return(i);
+ return(-1);
+}
+
+int
+bd_unit2bios(int unit)
+{
+ if ((unit >= 0) && (unit < nbdinfo))
+ return(bdinfo[unit].bd_unit);
+ return(-1);
+}
/*
* Quiz the BIOS for disk devices, save a little info about them.
@@ -120,18 +154,13 @@ bd_init(void)
/* sequence 0, 0x80 */
for (base = 0; base <= 0x80; base += 0x80) {
for (unit = base; (nbdinfo < MAXBDDEV); unit++) {
- bdinfo[nbdinfo].bd_unit = -1;
+ bdinfo[nbdinfo].bd_unit = unit;
bdinfo[nbdinfo].bd_flags = (unit < 0x80) ? BD_FLOPPY : 0;
-
- if (bd_edd3probe(unit)) {
- bdinfo[nbdinfo].bd_flags |= BD_MODEEDD3;
- } else if (bd_edd1probe(unit)) {
- bdinfo[nbdinfo].bd_flags |= BD_MODEEDD1;
- } else if (bd_int13probe(unit)) {
- bdinfo[nbdinfo].bd_flags |= BD_MODEINT13;
- } else {
+
+ /* XXX add EDD probes */
+ if (!bd_int13probe(&bdinfo[nbdinfo]))
break;
- }
+
/* XXX we need "disk aliases" to make this simpler */
printf("BIOS drive %c: is disk%d\n",
(unit < 0x80) ? ('A' + unit) : ('C' + unit - 0x80), nbdinfo);
@@ -142,40 +171,26 @@ bd_init(void)
return(0);
}
-/*
- * Try to detect a device supported by an Enhanced Disk Drive 3.0-compliant BIOS
- */
-static int
-bd_edd3probe(int unit)
-{
- return(0); /* XXX not implemented yet */
-}
-
-/*
- * Try to detect a device supported by an Enhanced Disk Drive 1.1-compliant BIOS
- */
-static int
-bd_edd1probe(int unit)
-{
- return(0); /* XXX not implemented yet */
-}
-
/*
* Try to detect a device supported by the legacy int13 BIOS
*/
static int
-bd_int13probe(int unit)
+bd_int13probe(struct bdinfo *bd)
{
+
v86.ctl = V86_FLAGS;
v86.addr = 0x13;
v86.eax = 0x800;
- v86.edx = unit;
+ v86.edx = bd->bd_unit;
v86int();
- if (!(v86.efl & 0x1) && /* carry clear */
- ((v86.edx & 0xff) > (unit & 0x7f))) /* unit # OK */
+ if (!(v86.efl & 0x1) && /* carry clear */
+ ((v86.edx & 0xff) > (bd->bd_unit & 0x7f))) { /* unit # OK */
+ bd->bd_flags |= BD_MODEINT13;
+ bd->bd_type = v86.ebx & 0xff;
return(1);
+ }
return(0);
}
@@ -193,11 +208,29 @@ static int
bd_open(struct open_file *f, void *vdev)
{
struct i386_devdesc *dev = (struct i386_devdesc *)vdev;
- struct dos_partition *dptr;
struct open_disk *od;
+ int error;
+
+ if ((error = bd_opendisk(&od, dev)))
+ return(error);
+
+ /*
+ * Save our context
+ */
+ ((struct i386_devdesc *)(f->f_devdata))->d_kind.biosdisk.data = od;
+ DEBUG("open_disk %p, partition at 0x%x", od, od->od_boff);
+ return(0);
+}
+
+static int
+bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev)
+{
+ struct dos_partition *dptr;
struct disklabel *lp;
+ struct open_disk *od;
int sector, slice, i;
int error;
+ u_char buf[BUFSIZE];
if (dev->d_kind.biosdisk.unit >= nbdinfo) {
DEBUG("attempt to open nonexistent disk");
@@ -236,7 +269,7 @@ bd_open(struct open_file *f, void *vdev)
/*
* Find the slice in the DOS slice table.
*/
- if (bd_read(od, 0, 1, od->od_buf)) {
+ if (bd_read(od, 0, 1, buf)) {
DEBUG("error reading MBR");
error = EIO;
goto out;
@@ -245,7 +278,7 @@ bd_open(struct open_file *f, void *vdev)
/*
* Check the slice table magic.
*/
- if ((od->od_buf[0x1fe] != 0x55) || (od->od_buf[0x1ff] != 0xaa)) {
+ if ((buf[0x1fe] != 0x55) || (buf[0x1ff] != 0xaa)) {
/* If a slice number was explicitly supplied, this is an error */
if (dev->d_kind.biosdisk.slice > 0) {
DEBUG("no slice table/MBR (no magic)");
@@ -255,7 +288,9 @@ bd_open(struct open_file *f, void *vdev)
sector = 0;
goto unsliced; /* may be a floppy */
}
- dptr = (struct dos_partition *) & od->od_buf[DOSPARTOFF];
+ bcopy(buf + DOSPARTOFF, &od->od_parttab, sizeof(struct dos_partition));
+ dptr = &od->od_parttab;
+ od->od_flags |= BD_PARTTABOK;
/*
* XXX No support here for 'extended' slices
@@ -299,12 +334,15 @@ bd_open(struct open_file *f, void *vdev)
DEBUG("opening raw slice");
} else {
- if (bd_read(od, sector + LABELSECTOR, 1, od->od_buf)) {
+ if (bd_read(od, sector + LABELSECTOR, 1, buf)) {
DEBUG("error reading disklabel");
error = EIO;
goto out;
}
- lp = (struct disklabel *) (od->od_buf + LABELOFFSET);
+ DEBUG("copy %d bytes of label from %p to %p", sizeof(struct disklabel), buf + LABELOFFSET, &od->od_disklabel);
+ bcopy(buf + LABELOFFSET, &od->od_disklabel, sizeof(struct disklabel));
+ lp = &od->od_disklabel;
+ od->od_flags |= BD_LABELOK;
if (lp->d_magic != DISKMAGIC) {
DEBUG("no disklabel");
@@ -326,23 +364,29 @@ bd_open(struct open_file *f, void *vdev)
od->od_boff = lp->d_partitions[dev->d_kind.biosdisk.partition].p_offset;
}
- /*
- * Save our context
- */
- ((struct i386_devdesc *)(f->f_devdata))->d_kind.biosdisk.data = od;
- DEBUG("open_disk %p, partition at 0x%x", od, od->od_boff);
-
+
out:
- if (error)
+ if (error) {
free(od);
+ } else {
+ *odp = od; /* return the open disk */
+ }
return(error);
}
+
static int
bd_close(struct open_file *f)
{
struct open_disk *od = (struct open_disk *)(((struct i386_devdesc *)(f->f_devdata))->d_kind.biosdisk.data);
+ bd_closedisk(od);
+ return(0);
+}
+
+static void
+bd_closedisk(struct open_disk *od)
+{
DEBUG("open_disk %p", od);
#if 0
/* XXX is this required? (especially if disk already open...) */
@@ -350,7 +394,6 @@ bd_close(struct open_file *f)
delay(3000000);
#endif
free(od);
- return(0);
}
static int
@@ -521,3 +564,45 @@ bd_getgeom(struct open_disk *od)
DEBUG("unit 0x%x geometry %d/%d/%d", od->od_unit, od->od_cyl, od->od_hds, od->od_sec);
return(0);
}
+
+/*
+ * Return a suitable dev_t value for (dev)
+ */
+int
+bd_getdev(struct i386_devdesc *dev)
+{
+ struct open_disk *od;
+ int biosdev;
+ int major;
+
+ biosdev = bd_unit2bios(dev->d_kind.biosdisk.unit);
+ if (biosdev == -1) /* not a BIOS device */
+ return(-1);
+ if (bd_opendisk(&od, dev) != 0) /* oops, not a viable device */
+ return(-1);
+
+ if (biosdev < 0x80) {
+ /* floppy (or emulated floppy) or ATAPI device */
+ if (bdinfo[dev->d_kind.biosdisk.unit].bd_type == DT_ATAPI) {
+ /* is an ATAPI disk */
+ major = WFDMAJOR;
+ } else {
+ /* is a floppy disk */
+ major = FDMAJOR;
+ }
+ } else {
+ /* harddisk */
+ if ((od->od_flags & BD_LABELOK) && (od->od_disklabel.d_type == DTYPE_SCSI)) {
+ /* label OK, disk labelled as SCSI */
+ major = DAMAJOR;
+ } else {
+ /* assume an IDE disk */
+ major = WDMAJOR;
+ }
+ }
+ return(MAKEBOOTDEV(major,
+ (dev->d_kind.biosdisk.slice + 1) >> 4, /* XXX slices may be wrong here */
+ (dev->d_kind.biosdisk.slice + 1) & 0xf,
+ biosdev & 0x7f, /* XXX allow/compute shift for da when wd present */
+ dev->d_kind.biosdisk.partition));
+}
diff --git a/sys/boot/i386/libi386/comconsole.c b/sys/boot/i386/libi386/comconsole.c
index 1d98585bc54de..d493e7c2ab5e6 100644
--- a/sys/boot/i386/libi386/comconsole.c
+++ b/sys/boot/i386/libi386/comconsole.c
@@ -24,7 +24,7 @@
*
* From Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp
*
- * $Id: comconsole.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
+ * $Id: comconsole.c,v 1.2 1998/09/17 23:52:09 msmith Exp $
*/
#include <stand.h>
@@ -86,7 +86,7 @@ comc_getchar(void)
v86.addr = 0x14;
v86.eax = 0x300;
v86int();
- return(v86.eax);
+ return(v86.eax & 0xff);
} else {
return(-1);
}
diff --git a/sys/boot/i386/libi386/libi386.h b/sys/boot/i386/libi386/libi386.h
index 81f8e9b227d29..0ff88c334e472 100644
--- a/sys/boot/i386/libi386/libi386.h
+++ b/sys/boot/i386/libi386/libi386.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: libi386.h,v 1.5 1998/09/17 23:52:10 msmith Exp $
+ * $Id: libi386.h,v 1.6 1998/09/26 10:51:38 dfr Exp $
*/
@@ -63,22 +63,14 @@ extern struct devdesc currdev; /* our current device */
/* exported devices XXX rename? */
extern struct devsw biosdisk;
-/* from crt module */
-#if 0 /* BTX */
-extern void vpbcopy(void *src, vm_offset_t dest, size_t size);
-extern void pvbcopy(vm_offset_t src, void *dest, size_t size);
-extern void pbzero(vm_offset_t dest, size_t size);
-extern vm_offset_t vtophys(void *addr);
-#endif
+extern int bd_bios2unit(int biosdev); /* xlate BIOS device -> biosdisk unit */
+extern int bd_unit2bios(int unit); /* xlate biosdisk unit -> BIOS device */
+extern int bd_getdev(struct i386_devdesc *dev); /* return dev_t for (dev) */
extern int i386_copyin(void *src, vm_offset_t dest, size_t len);
extern int i386_copyout(vm_offset_t src, void *dest, size_t len);
extern int i386_readin(int fd, vm_offset_t dest, size_t len);
-#if 0 /* BTX */
-extern void startprog(vm_offset_t entry, int argc, u_int32_t *argv, vm_offset_t stack);
-#endif
-
extern int getbasemem(void);
extern int getextmem(void);
extern vm_offset_t memtop;
diff --git a/sys/boot/i386/libi386/vidconsole.c b/sys/boot/i386/libi386/vidconsole.c
index afd2a78499048..31f6fee266c99 100644
--- a/sys/boot/i386/libi386/vidconsole.c
+++ b/sys/boot/i386/libi386/vidconsole.c
@@ -26,7 +26,7 @@
*
* From Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp
*
- * $Id: vidconsole.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
+ * $Id: vidconsole.c,v 1.2 1998/09/17 23:52:10 msmith Exp $
*/
#include <stand.h>
@@ -97,7 +97,7 @@ vidc_getchar(void)
v86.addr = 0x16;
v86.eax = 0x0;
v86int();
- return(v86.eax);
+ return(v86.eax & 0xff);
} else {
return(-1);
}