diff options
| author | Mike Smith <msmith@FreeBSD.org> | 1998-10-02 16:32:45 +0000 |
|---|---|---|
| committer | Mike Smith <msmith@FreeBSD.org> | 1998-10-02 16:32:45 +0000 |
| commit | 6b15efd961c80cf9986157aea1370419b6385860 (patch) | |
| tree | 6b38031e2b89eb4dd97766826e30432917a293d9 /sys | |
| parent | 39de38225b3e84c7c1f3ce058bf922f966fbdef9 (diff) | |
Notes
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/boot/i386/libi386/aout_freebsd.c | 38 | ||||
| -rw-r--r-- | sys/boot/i386/libi386/biosdisk.c | 201 | ||||
| -rw-r--r-- | sys/boot/i386/libi386/comconsole.c | 4 | ||||
| -rw-r--r-- | sys/boot/i386/libi386/libi386.h | 16 | ||||
| -rw-r--r-- | sys/boot/i386/libi386/vidconsole.c | 4 |
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); } |
