Subject: Adding cd9660 support to the i386/amd64 BIOS bootloader
To: None <tech-install@netbsd.org>
From: Bang Jun-Young <junyoung@netbsd.org>
List: port-amd64
Date: 06/21/2005 23:39:09
--Boundary-00=_NaCuCN2P1fCtx/a
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Hi,
The attached patch adds cd9660 file system support to the i386/amd64 BIOS
bootloader. It allows you to boot the kernel directly from CD without floppy
disk emulation.
It has been tested with a number of real/virtual machines including Bochs,
VMware, ASUS/Pentium, ASUS/Athlon, Gigabyte/Duron, Soltek/Athlon XP, an
amd64 machine, and a Fujitsu laptop. It just worked fine.
The only MI change is in sys/lib/libsa/cd9660.c:
-#define cdb2devb(bno) ((bno) * ISO_DEFAULT_BLOCK_SIZE / DEV_BSIZE)
+#define cdb2devb(bno) (bno)
On i386, DEV_BSIZE on CD-ROM drives should be the same as
ISO_DEFAULT_BLOCK_SIZE, otherwise CD-ROM can't boot.
Any comments? I'm going to commit the patch in 48 hours unless there are
objections.
Jun-Young
--Boundary-00=_NaCuCN2P1fCtx/a
Content-Type: text/x-diff;
charset="us-ascii";
name="cdboot-20050621.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="cdboot-20050621.diff"
? sys/arch/i386/stand/lib/getbasemem.c
Index: sys/arch/i386/stand/boot/Makefile.boot
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/boot/Makefile.boot,v
retrieving revision 1.21
diff -u -r1.21 Makefile.boot
--- sys/arch/i386/stand/boot/Makefile.boot 27 May 2005 21:40:09 -0000 1.21
+++ sys/arch/i386/stand/boot/Makefile.boot 21 Jun 2005 14:22:19 -0000
@@ -62,6 +62,7 @@
CPPFLAGS+= -DCONSADDR=boot_params.bp_consaddr
CPPFLAGS+= -DCONSOLE_KEYMAP=boot_params.bp_keymap
+CPPFLAGS+= -DSUPPORT_CD9660
CPPFLAGS+= -DSUPPORT_USTARFS
CPPFLAGS+= -DSUPPORT_DOSFS
CPPFLAGS+= -DPASS_BIOSGEOM
@@ -139,7 +140,7 @@
CLEANFILES+= ${PROG}.tmp ${PROG}.map vers.c
-vers.c: ${VERSIONFILE} ${SOURCES} ${.CURDIR}/../Makefile.boot
+vers.c: ${VERSIONFILE} ${SOURCES} ${LIBLIST} ${.CURDIR}/../Makefile.boot
${HOST_SH} ${S}conf/newvers_stand.sh ${VERSIONFILE} ${MACHINE} ${NEWVERSWHAT}
# Anything that calls 'real_to_prot' must have a %pc < 0x10000.
Index: sys/arch/i386/stand/boot/boot2.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/boot/boot2.c,v
retrieving revision 1.10
diff -u -r1.10 boot2.c
--- sys/arch/i386/stand/boot/boot2.c 21 Jun 2005 14:20:35 -0000 1.10
+++ sys/arch/i386/stand/boot/boot2.c 21 Jun 2005 14:22:19 -0000
@@ -1,4 +1,4 @@
-/* $NetBSD: boot2.c,v 1.10 2005/06/21 14:20:35 junyoung Exp $ */
+/* $NetBSD: boot2.c,v 1.7 2005/06/15 19:07:36 junyoung Exp $ */
/*
* Copyright (c) 2003
@@ -56,15 +56,16 @@
#include <biosmca.h>
#endif
-int errno;
-extern int boot_biosdev;
-extern int boot_biossector; /* may be wrong... */
-
extern struct x86_boot_params boot_params;
extern const char bootprog_name[], bootprog_rev[], bootprog_date[],
bootprog_maker[];
+int errno;
+
+int boot_biosdev;
+u_int boot_biossector;
+
static const char * const names[][2] = {
{ "netbsd", "netbsd.gz" },
{ "onetbsd", "onetbsd.gz" },
@@ -83,7 +84,7 @@
char *sprint_bootsel(const char *);
void bootit(const char *, int, int);
void print_banner(void);
-void boot2(u_int, u_int);
+void boot2(int, u_int);
void command_help(char *);
void command_ls(char *);
@@ -105,11 +106,12 @@
int
parsebootfile(const char *fname, char **fsname, char **devname,
- u_int *unit, u_int *partition, const char **file)
+ int *unit, int *partition, const char **file)
{
const char *col;
- *fsname = "ufs";
+ if (fsname != NULL)
+ *fsname = "ufs";
*devname = default_devname;
*unit = default_unit;
*partition = default_partition;
@@ -121,7 +123,7 @@
if ((col = strchr(fname, ':')) != NULL) { /* device given */
static char savedevname[MAXDEVNAME+1];
int devlen;
- u_int u = 0, p = 0;
+ int u = 0, p = 0;
int i = 0;
devlen = col - fname;
@@ -172,12 +174,12 @@
char *
sprint_bootsel(const char *filename)
{
- char *fsname, *devname;
+ char *devname;
int unit, partition;
const char *file;
static char buf[80];
- if (parsebootfile(filename, &fsname, &devname, &unit,
+ if (parsebootfile(filename, NULL, &devname, &unit,
&partition, &file) == 0) {
sprintf(buf, "%s%d%c:%s", devname, unit, 'a' + partition, file);
return buf;
@@ -213,8 +215,14 @@
printf(">> Memory: %d/%d k\n", getbasemem(), getextmem());
}
+/*
+ * Called from the initial entry point boot_start in biosboot.S
+ *
+ * biosdev: BIOS drive number the system booted from
+ * biossector: Sector number of the NetBSD partition
+ */
void
-boot2(u_int boot_biosdev, u_int boot_biossector)
+boot2(int biosdev, u_int biossector)
{
int currname;
char c;
@@ -231,9 +239,13 @@
print_banner();
+ /* need to remember these */
+ boot_biosdev = biosdev;
+ boot_biossector = biossector;
+
/* try to set default device to what BIOS tells us */
- bios2dev(boot_biosdev, &default_devname, &default_unit,
- boot_biossector, &default_partition);
+ bios2dev(biosdev, biossector, &default_devname, &default_unit,
+ &default_partition);
/* if the user types "boot" without filename */
default_filename = DEFFILENAME;
@@ -315,7 +327,7 @@
command_dev(char *arg)
{
static char savedevname[MAXDEVNAME + 1];
- char *fsname, *devname;
+ char *devname;
const char *file; /* dummy */
if (*arg == '\0') {
@@ -325,7 +337,7 @@
}
if (strchr(arg, ':') != NULL ||
- parsebootfile(arg, &fsname, &devname, &default_unit,
+ parsebootfile(arg, NULL, &devname, &default_unit,
&default_partition, &file)) {
command_help(NULL);
return;
Index: sys/arch/i386/stand/boot/conf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/boot/conf.c,v
retrieving revision 1.2
diff -u -r1.2 conf.c
--- sys/arch/i386/stand/boot/conf.c 24 Mar 2004 16:54:18 -0000 1.2
+++ sys/arch/i386/stand/boot/conf.c 21 Jun 2005 14:22:19 -0000
@@ -39,6 +39,9 @@
#ifdef SUPPORT_DOSFS
#include <lib/libsa/dosfs.h>
#endif
+#ifdef SUPPORT_CD9660
+#include <lib/libsa/cd9660.h>
+#endif
#include <biosdisk.h>
@@ -48,6 +51,9 @@
int ndevs = sizeof(devsw) / sizeof(struct devsw);
struct fs_ops file_system[] = {
+#ifdef SUPPORT_CD9660
+ FS_OPS(cd9660),
+#endif
#ifdef SUPPORT_USTARFS
FS_OPS(ustarfs),
#endif
Index: sys/arch/i386/stand/boot/devopen.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/boot/devopen.c,v
retrieving revision 1.3
diff -u -r1.3 devopen.c
--- sys/arch/i386/stand/boot/devopen.c 15 Jun 2005 19:01:19 -0000 1.3
+++ sys/arch/i386/stand/boot/devopen.c 21 Jun 2005 14:22:19 -0000
@@ -1,5 +1,41 @@
/* $NetBSD: devopen.c,v 1.3 2005/06/15 19:01:19 junyoung Exp $ */
+/*-
+ * Copyright (c) 2005 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Bang Jun-Young.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
/*
* Copyright (c) 1996, 1997
* Matthias Drochner. All rights reserved.
@@ -41,33 +77,46 @@
#include <biosmca.h>
#endif
-static int dev2bios(char *, u_int, int *);
+static int dev2bios(char *, int, int *);
static int
-dev2bios(char *devname, u_int unit, int *biosdev)
+dev2bios(char *devname, int unit, int *biosdev)
{
+
if (strcmp(devname, "hd") == 0)
*biosdev = 0x80 + unit;
else if (strcmp(devname, "fd") == 0)
*biosdev = 0x00 + unit;
+ else if (strcmp(devname, "cd") == 0)
+ *biosdev = boot_biosdev;
else
return ENXIO;
return 0;
}
-int
-bios2dev(int biosdev, char **devname, u_int *unit, u_int sector, u_int *ptnp)
+void
+bios2dev(int biosdev, u_int sector, char **devname, int *unit, int *partition)
{
- if (biosdev & 0x80)
- *devname = "hd";
- else
- *devname = "fd";
+ /* set default */
*unit = biosdev & 0x7f;
- *ptnp = biosdiskfindptn(biosdev, sector);
- return 0;
+ if (biosdev & 0x80) {
+ /*
+ * There seems to be no standard way of numbering BIOS
+ * CD-ROM drives. The following method is a little tricky
+ * but works nicely.
+ */
+ if (biosdev >= 0x80 + get_harddrives()) {
+ *devname = "cd";
+ *unit = 0; /* override default */
+ } else
+ *devname = "hd";
+ } else
+ *devname = "fd";
+
+ *partition = biosdiskfindptn(biosdev, sector);
}
#ifdef _STANDALONE
@@ -81,7 +130,7 @@
devopen(struct open_file *f, const char *fname, char **file)
{
char *fsname, *devname;
- u_int unit, partition;
+ int unit, partition;
int biosdev;
int error;
Index: sys/arch/i386/stand/boot/devopen.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/boot/devopen.h,v
retrieving revision 1.1
diff -u -r1.1 devopen.h
--- sys/arch/i386/stand/boot/devopen.h 16 Apr 2003 22:36:14 -0000 1.1
+++ sys/arch/i386/stand/boot/devopen.h 21 Jun 2005 14:22:19 -0000
@@ -1,3 +1,5 @@
-/* $NetBSD: devopen.h,v 1.1 2003/04/16 22:36:14 dsl Exp $ */
+/* $NetBSD: devopen.h,v 1.1 2003/04/16 22:36:14 dsl Exp $ */
-int bios2dev(int, char **, u_int *, u_int, u_int *);
+extern int boot_biosdev;
+
+void bios2dev(int, u_int, char **, int *, int *);
Index: sys/arch/i386/stand/boot/version
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/boot/version,v
retrieving revision 1.3
diff -u -r1.3 version
--- sys/arch/i386/stand/boot/version 23 Oct 2004 17:20:04 -0000 1.3
+++ sys/arch/i386/stand/boot/version 21 Jun 2005 14:22:19 -0000
@@ -35,3 +35,4 @@
Leave space in bootxx for FAT32 BPB and MBR partition table.
Keep MBR's existing BPB and partition table when installing bootxx.
3.2: Add support for passing boot wedge information to the kernel.
+3.3: Add support for cd9660 file system.
Index: sys/arch/i386/stand/lib/Makefile
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/Makefile,v
retrieving revision 1.22
diff -u -r1.22 Makefile
--- sys/arch/i386/stand/lib/Makefile 16 Apr 2003 22:30:40 -0000 1.22
+++ sys/arch/i386/stand/lib/Makefile 21 Jun 2005 14:22:19 -0000
@@ -18,7 +18,7 @@
SRCS= pcio.c conio.S comio.S comio_direct.c biosvideomode.S
SRCS+= getsecs.c biosgetrtc.S biosdelay.S biosreboot.S gatea20.c
-SRCS+= biosmem.S getextmemx.c biosmemx.S printmemlist.c
+SRCS+= biosmem.S getbasemem.c getextmemx.c biosmemx.S printmemlist.c
SRCS+= pread.c menuutils.c parseutils.c
SRCS+= bootinfo.c bootinfo_biosgeom.c bootinfo_memmap.c
SRCS+= startprog.S panic.c
Index: sys/arch/i386/stand/lib/biosdisk.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/biosdisk.c,v
retrieving revision 1.22
diff -u -r1.22 biosdisk.c
--- sys/arch/i386/stand/lib/biosdisk.c 13 Jun 2005 11:23:28 -0000 1.22
+++ sys/arch/i386/stand/lib/biosdisk.c 21 Jun 2005 14:22:19 -0000
@@ -78,7 +78,7 @@
#include "bootinfo.h"
#endif
-#define BUFSIZE (1 * BIOSDISK_SECSIZE)
+#define BUFSIZE 2048 /* must be large enough for a CD sector */
struct biosdisk {
struct biosdisk_ll ll;
@@ -93,8 +93,6 @@
#define RF_PROTECTED_SECTORS 64 /* XXX refer to <.../rf_optnames.h> */
-int boot_biossector; /* disk sector partition might have started in */
-
int
biosdiskstrategy(void *devdata, int flag, daddr_t dblk, size_t size,
void *buf, size_t *rsize)
@@ -109,22 +107,22 @@
dblk += d->boff;
- blks = size / BIOSDISK_SECSIZE;
+ blks = size / d->ll.secsize;
if (blks && readsects(&d->ll, dblk, blks, buf, 0)) {
if (rsize)
*rsize = 0;
return EIO;
}
- /* do we really need this? */
- frag = size % BIOSDISK_SECSIZE;
+ /* needed for CD */
+ frag = size % d->ll.secsize;
if (frag) {
if (readsects(&d->ll, dblk + blks, 1, d->buf, 0)) {
if (rsize)
- *rsize = blks * BIOSDISK_SECSIZE;
+ *rsize = blks * d->ll.secsize;
return EIO;
}
- memcpy(buf + blks * BIOSDISK_SECSIZE, d->buf, frag);
+ memcpy(buf + blks * d->ll.secsize, d->buf, frag);
}
if (rsize)
@@ -133,21 +131,21 @@
}
static struct biosdisk *
-alloc_biosdisk(int dev)
+alloc_biosdisk(int biosdev)
{
struct biosdisk *d;
- d = alloc(sizeof *d);
+ d = alloc(sizeof(*d));
if (d == NULL)
return NULL;
- memset(d, 0, sizeof *d);
+ memset(d, 0, sizeof(*d));
- d->ll.dev = dev;
+ d->ll.dev = biosdev;
if (set_geometry(&d->ll, NULL)) {
#ifdef DISK_DEBUG
printf("no geometry information\n");
#endif
- free(d, sizeof *d);
+ free(d, sizeof(*d));
return NULL;
}
return d;
@@ -192,13 +190,13 @@
int sector_386bsd = -1;
#endif
- memset(&dflt_lbl, 0, sizeof dflt_lbl);
+ memset(&dflt_lbl, 0, sizeof(dflt_lbl));
dflt_lbl.d_npartitions = 8;
d->boff = 0;
- if (!(d->ll.dev & 0x80)) /* floppy */
- /* No label on floppy */
+ if (d->ll.type != BIOSDISK_TYPE_HD)
+ /* No label on floppy or CD */
return -1;
/*
@@ -216,7 +214,8 @@
#endif
return EIO;
}
- memcpy(&mbr, ((struct mbr_sector *)d->buf)->mbr_parts, sizeof mbr);
+ memcpy(&mbr, ((struct mbr_sector *)d->buf)->mbr_parts,
+ sizeof(mbr));
/* Look for NetBSD partition ID */
for (i = 0; i < MBR_PART_COUNT; i++) {
typ = mbr[i].mbrp_type;
@@ -279,7 +278,7 @@
*/
/* XXX fill it to make checksum match kernel one */
dflt_lbl.d_checksum = dkcksum(&dflt_lbl);
- memcpy(d->buf, &dflt_lbl, sizeof dflt_lbl);
+ memcpy(d->buf, &dflt_lbl, sizeof(dflt_lbl));
return -1;
}
#endif /* NO_DISKLABEL */
@@ -288,14 +287,14 @@
* partition.
*/
-u_int
+int
biosdiskfindptn(int biosdev, u_int sector)
{
#ifdef NO_DISKLABEL
return 0;
#else
struct biosdisk *d;
- u_int partition = 0;
+ int partition = 0;
struct disklabel *lp;
/* Look for netbsd partition that is the dos boot one */
@@ -313,17 +312,18 @@
}
}
- free(d, sizeof *d);
+ free(d, sizeof(*d));
return partition;
#endif /* NO_DISKLABEL */
}
int
biosdiskopen(struct open_file *f, ...)
-/* file, biosdev, partition */
+/* struct open_file *f, int biosdev, int partition */
{
va_list ap;
struct biosdisk *d;
+ int biosdev;
int partition;
#ifndef NO_DISKLABEL
struct disklabel *lp;
@@ -331,8 +331,9 @@
int error = 0;
va_start(ap, f);
- d = alloc_biosdisk(va_arg(ap, int));
- if (!d) {
+ biosdev = va_arg(ap, int);
+ d = alloc_biosdisk(biosdev);
+ if (d == NULL) {
error = ENXIO;
goto out;
}
@@ -360,7 +361,7 @@
lp = (struct disklabel *) (d->buf + LABELOFFSET);
if (partition >= lp->d_npartitions ||
- lp->d_partitions[partition].p_fstype == FS_UNUSED) {
+ lp->d_partitions[partition].p_fstype == FS_UNUSED) {
#ifdef DISK_DEBUG
printf("illegal partition\n");
#endif
@@ -414,7 +415,8 @@
{
struct biosdisk *d = f->f_devdata;
- if (!(d->ll.dev & 0x80))/* let the floppy drive go off */
+ /* let the floppy drive go off */
+ if (d->ll.type == BIOSDISK_TYPE_FD)
delay(3000000); /* 2s is enough on all PCs I found */
free(d, sizeof(struct biosdisk));
Index: sys/arch/i386/stand/lib/biosdisk.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/biosdisk.h,v
retrieving revision 1.4
diff -u -r1.4 biosdisk.h
--- sys/arch/i386/stand/lib/biosdisk.h 24 Mar 2004 16:46:27 -0000 1.4
+++ sys/arch/i386/stand/lib/biosdisk.h 21 Jun 2005 14:22:19 -0000
@@ -29,5 +29,5 @@
int biosdiskopen(struct open_file *, ...);
int biosdiskclose(struct open_file *);
int biosdiskioctl(struct open_file *, u_long, void *);
-u_int biosdiskfindptn(int, u_int);
+int biosdiskfindptn(int, u_int);
Index: sys/arch/i386/stand/lib/biosdisk_ll.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/biosdisk_ll.c,v
retrieving revision 1.20
diff -u -r1.20 biosdisk_ll.c
--- sys/arch/i386/stand/lib/biosdisk_ll.c 13 Jun 2005 11:27:40 -0000 1.20
+++ sys/arch/i386/stand/lib/biosdisk_ll.c 21 Jun 2005 14:22:19 -0000
@@ -1,5 +1,41 @@
/* $NetBSD: biosdisk_ll.c,v 1.20 2005/06/13 11:27:40 junyoung Exp $ */
+/*-
+ * Copyright (c) 2005 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Bang Jun-Young.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
/*
* Copyright (c) 1996
* Matthias Drochner. All rights reserved.
@@ -50,8 +86,8 @@
/*
* we get from get_diskinfo():
- * xxxx %ch %cl %dh (registers after int13/8), ie
- * xxxx cccc Csss hhhh
+ * unused %ch %cl %dh (registers after int13/8), ie
+ * xxxxxxxx cccccccc CCssssss hhhhhhhh
*/
#define SPT(di) (((di)>>8)&0x3f)
#define HEADS(di) (((di)&0xff)+1)
@@ -65,7 +101,6 @@
set_geometry(struct biosdisk_ll *d, struct biosdisk_ext13info *ed)
{
int diskinfo;
- char buf[512];
diskinfo = get_diskinfo(d->dev);
d->sec = SPT(diskinfo);
@@ -73,11 +108,31 @@
d->cyl = CYL(diskinfo);
d->chs_sectors = d->sec * d->head * d->cyl;
+ if (d->dev >= 0x80 + get_harddrives()) {
+ d->secsize = 2048;
+ d->type = BIOSDISK_TYPE_CD;
+ } else {
+ d->secsize = 512;
+ if (d->dev & 0x80)
+ d->type = BIOSDISK_TYPE_HD;
+ else
+ d->type = BIOSDISK_TYPE_FD;
+ }
+
+ /*
+ * Some broken BIOSes such as one found on Soltek SL-75DRV2 report
+ * that they don't support int13 extension for CD-ROM drives while
+ * they actually do. As a workaround, if the boot device is a CD we
+ * assume that the extension is available. Note that only very old
+ * BIOSes don't support the extended mode, and they don't work with
+ * ATAPI CD-ROM drives, either. So there's no problem.
+ */
d->flags = 0;
- if ((d->dev & 0x80) && int13_extension(d->dev)) {
+ if (d->type == BIOSDISK_TYPE_CD ||
+ (d->type == BIOSDISK_TYPE_HD && int13_extension(d->dev))) {
d->flags |= BIOSDISK_EXT13;
if (ed != NULL) {
- ed->size = sizeof *ed;
+ ed->size = sizeof(*ed);
int13_getextinfo(d->dev, ed);
}
}
@@ -86,18 +141,16 @@
* If the drive is 2.88MB floppy drive, check that we can actually
* read sector >= 18. If not, assume 1.44MB floppy disk.
*/
- if (d->dev == 0 && SPT(diskinfo) == 36) {
+ if (d->type == BIOSDISK_TYPE_FD && SPT(diskinfo) == 36) {
+ char buf[512];
+
if (biosread(d->dev, 0, 0, 18, 1, buf)) {
d->sec = 18;
d->chs_sectors /= 2;
}
}
- /*
- * get_diskinfo assumes floppy if BIOS call fails. Check at least
- * "valid" geometry.
- */
- return (!d->sec || !d->head);
+ return 0;
}
/*
@@ -105,7 +158,6 @@
* floppies, the bootstrap has to be loaded on a 64K boundary to ensure that
* this buffer doesn't cross a 64K DMA boundary.
*/
-#define RA_SECTORS (DISKBUFSIZE / BIOSDISK_SECSIZE)
static int ra_dev;
static int ra_end;
static int ra_first;
@@ -126,23 +178,25 @@
(((d)->dev & 0x80) != 0)
#else
#define NEED_INT13EXT(d, dblk, num) \
- (((d)->dev & 0x80) != 0 && ((dblk) + (num)) >= (d)->chs_sectors)
+ (((d)->type == BIOSDISK_TYPE_CD) || \
+ ((d)->type == BIOSDISK_TYPE_HD && \
+ ((dblk) + (num)) >= (d)->chs_sectors))
#endif
static int
do_read(struct biosdisk_ll *d, daddr_t dblk, int num, char *buf)
{
- int cyl, head, sec, nsec, spc, dblk32;
- struct {
- int8_t size;
- int8_t resvd;
- int16_t cnt;
- int16_t off;
- int16_t seg;
- int64_t sec;
- } ext;
if (NEED_INT13EXT(d, dblk, num)) {
+ struct {
+ int8_t size;
+ int8_t resvd;
+ int16_t cnt;
+ int16_t off;
+ int16_t seg;
+ int64_t sec;
+ } ext;
+
if (!(d->flags & BIOSDISK_EXT13))
return -1;
ext.size = sizeof(ext);
@@ -160,6 +214,8 @@
return ext.cnt;
} else {
+ int cyl, head, sec, nsec, spc, dblk32;
+
dblk32 = (int)dblk;
spc = d->head * d->sec;
cyl = dblk32 / spc;
@@ -179,11 +235,10 @@
}
}
-/* NB if 'cold' is set below not all of the program is loaded, so
- * musn't use data segment, bss, call library functions or do
- * read-ahead.
+/*
+ * NB if 'cold' is set below not all of the program is loaded, so
+ * mustn't use data segment, bss, call library functions or do read-ahead.
*/
-
int
readsects(struct biosdisk_ll *d, daddr_t dblk, int num, char *buf, int cold)
{
@@ -209,7 +264,7 @@
} else {
/* fill read-ahead buffer */
trbuf = alloc_diskbuf(0); /* no data yet */
- maxsecs = RA_SECTORS;
+ maxsecs = DISKBUFSIZE / d->secsize;
}
while ((nsec = do_read(d, dblk, maxsecs, trbuf)) < 0) {
@@ -238,13 +293,31 @@
if (nsec > num)
nsec = num;
memcpy(buf,
- diskbufp + (dblk - ra_first) * BIOSDISK_SECSIZE,
- nsec * BIOSDISK_SECSIZE);
+ diskbufp + (dblk - ra_first) * d->secsize,
+ nsec * d->secsize);
}
- buf += nsec * BIOSDISK_SECSIZE;
+ buf += nsec * d->secsize;
num -= nsec;
dblk += nsec;
}
return 0;
}
+
+/*
+ * Return the number of hard disk drives.
+ */
+int
+get_harddrives(void)
+{
+ /*
+ * Some BIOSes are buggy so that they return incorrect number
+ * of hard drives with int13/ah=8. We read a byte at 0040:0075
+ * instead, which is known to be always correct.
+ */
+ int n = 0;
+
+ pvbcopy((void *)0x475, &n, 1);
+
+ return n;
+}
Index: sys/arch/i386/stand/lib/biosdisk_ll.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/biosdisk_ll.h,v
retrieving revision 1.10
diff -u -r1.10 biosdisk_ll.h
--- sys/arch/i386/stand/lib/biosdisk_ll.h 13 Jun 2005 11:34:11 -0000 1.10
+++ sys/arch/i386/stand/lib/biosdisk_ll.h 21 Jun 2005 14:22:19 -0000
@@ -46,12 +46,18 @@
*/
struct biosdisk_ll {
int dev; /* BIOS device number */
+ int type; /* device type; see below */
int sec, head, cyl; /* geometry */
int flags; /* see below */
int chs_sectors; /* # of sectors addressable by CHS */
+ int secsize; /* bytes per sector */
};
#define BIOSDISK_EXT13 1 /* BIOS supports int13 extension */
+#define BIOSDISK_TYPE_FD 0
+#define BIOSDISK_TYPE_HD 1
+#define BIOSDISK_TYPE_CD 2
+
/*
* Version 1.x drive parameters from int13 extensions
* - should be supported by every BIOS that supports the extensions.
@@ -114,7 +120,5 @@
#define EXT13_LOCKABLE 0x0020 /* device is lockable */
#define EXT13_MAXGEOM 0x0040 /* geometry set to max; no media */
-#define BIOSDISK_SECSIZE 512
-
int set_geometry(struct biosdisk_ll *, struct biosdisk_ext13info *);
int readsects(struct biosdisk_ll *, daddr_t, int, char *, int);
Index: sys/arch/i386/stand/lib/biosmem.S
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/biosmem.S,v
retrieving revision 1.6
diff -u -r1.6 biosmem.S
--- sys/arch/i386/stand/lib/biosmem.S 1 Feb 2003 14:48:18 -0000 1.6
+++ sys/arch/i386/stand/lib/biosmem.S 21 Jun 2005 14:22:19 -0000
@@ -31,42 +31,12 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-
-#include <machine/asm.h>
-#define data32 .byte 0x66
+#include <machine/asm.h>
.text
-/* get mem below 1M, in kByte */
-
-ENTRY(getbasemem)
- pushl %ebp
- movl %esp,%ebp
- pushl %ebx
- push %esi
- push %edi
-
- call _C_LABEL(prot_to_real)
- .code16
-
- int $0x12
- # zero-extend 16-bit result to 32 bits.
- movl $0, %ebx
- mov %ax,%bx
-
- calll _C_LABEL(real_to_prot)
- .code32
-
- movl %ebx, %eax
-
- pop %edi
- pop %esi
- popl %ebx
- popl %ebp
- ret
-
/* get mem above 1M, in kByte */
ENTRY(getextmem1)
Index: sys/arch/i386/stand/lib/bootinfo_biosgeom.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/bootinfo_biosgeom.c,v
retrieving revision 1.13
diff -u -r1.13 bootinfo_biosgeom.c
--- sys/arch/i386/stand/lib/bootinfo_biosgeom.c 24 Mar 2004 16:46:28 -0000 1.13
+++ sys/arch/i386/stand/lib/bootinfo_biosgeom.c 21 Jun 2005 14:22:19 -0000
@@ -37,6 +37,8 @@
#include "biosdisk_ll.h"
#include "bootinfo.h"
+#define BIOSDISK_SECSIZE 512 /* XXX */
+
#ifdef BIOSDISK_EXT13INFO_V3
static struct {
char *name;
@@ -56,27 +58,28 @@
{NULL, BI_GEOM_IFACE_OTHER} };
#endif
-void bi_getbiosgeom()
+void
+bi_getbiosgeom(void)
{
struct btinfo_biosgeom *bibg;
int i, j, nvalid;
- unsigned char nhd;
+ int nhd;
unsigned int cksum;
struct biosdisk_ll d;
struct biosdisk_ext13info ed;
char buf[BIOSDISK_SECSIZE];
- pvbcopy((void *)(0x400 + 0x75), &nhd, 1);
+ nhd = get_harddrives();
#ifdef GEOM_DEBUG
- printf("nhd %d\n", (int)nhd);
+ printf("nhd %d\n", nhd);
#endif
bibg = alloc(sizeof(struct btinfo_biosgeom)
+ (nhd - 1) * sizeof(struct bi_biosgeom_entry));
- if (!bibg)
+ if (bibg == NULL)
return;
- for (i = nvalid = 0; i < MAX_BIOSDISKS && nvalid < (int)nhd; i++) {
+ for (i = nvalid = 0; i < MAX_BIOSDISKS && nvalid < nhd; i++) {
d.dev = 0x80 + i;
@@ -97,10 +100,10 @@
#ifdef GEOM_DEBUG
printf("#%d: %x: C %d H %d S %d\n", nvalid,
- d.dev, d.cyl, d.head, d.sec);
+ d.dev, d.cyl, d.head, d.sec);
printf(" sz %d fl %x cyl %d head %d sec %d totsec %lld sbytes %d\n",
- ed.size, ed.flags, ed.cyl, ed.head, ed.sec,
- ed.totsec, ed.sbytes);
+ ed.size, ed.flags, ed.cyl, ed.head, ed.sec,
+ ed.totsec, ed.sbytes);
#endif
if (d.flags & BIOSDISK_EXT13) {
@@ -110,8 +113,8 @@
#ifdef BIOSDISK_EXT13INFO_V3
#ifdef GEOM_DEBUG
printf(" edd_cfg %x, sig %x, len %x, bus %s type %s\n",
- ed.edd_cfg, ed.devpath_sig, ed.devpath_len,
- ed.host_bus, ed.iface_type);
+ ed.edd_cfg, ed.devpath_sig, ed.devpath_len,
+ ed.host_bus, ed.iface_type);
#endif
/* The v3.0 stuff will help identify the disks */
@@ -120,7 +123,7 @@
char *cp;
for (cp = (void *)&ed.devpath_sig, cksum = 0;
- cp <= (char *)&ed.checksum; cp++) {
+ cp <= (char *)&ed.checksum; cp++) {
cksum += *cp;
}
if ((cksum & 0xff) != 0)
@@ -133,12 +136,12 @@
if (cp == NULL)
break;
if (strncmp(cp, ed.host_bus,
- sizeof ed.host_bus) == 0)
+ sizeof(ed.host_bus)) == 0)
break;
}
#ifdef GEOM_DEBUG
printf("bus %s (%x)\n", cp ? cp : "null",
- bus_names[j].flag);
+ bus_names[j].flag);
#endif
bibg->disk[nvalid].flags |= bus_names[j].flag;
for (j = 0; ; j++) {
@@ -146,7 +149,7 @@
if (cp == NULL)
break;
if (strncmp(cp, ed.iface_type,
- sizeof ed.iface_type) == 0)
+ sizeof(ed.iface_type)) == 0)
break;
}
bibg->disk[nvalid].flags |= iface_names[j].flag;
@@ -157,10 +160,10 @@
ed.device_path.dp_64[0];
#ifdef GEOM_DEBUG
printf("device %s (%x) interface %x path %llx\n",
- cp ? cp : "null",
- iface_names[j].flag,
- ed.interface_path.ip_32[0],
- ed.device_path.dp_64[0]);
+ cp ? cp : "null",
+ iface_names[j].flag,
+ ed.interface_path.ip_32[0],
+ ed.device_path.dp_64[0]);
#endif
}
#endif
@@ -169,7 +172,7 @@
cksum += buf[j];
bibg->disk[nvalid].cksum = cksum;
memcpy(bibg->disk[nvalid].dosparts, &buf[MBR_PART_OFFSET],
- sizeof(bibg->disk[nvalid].dosparts));
+ sizeof(bibg->disk[nvalid].dosparts));
nvalid++;
}
Index: sys/arch/i386/stand/lib/exec.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/exec.c,v
retrieving revision 1.20
diff -u -r1.20 exec.c
--- sys/arch/i386/stand/lib/exec.c 10 Nov 2003 08:51:52 -0000 1.20
+++ sys/arch/i386/stand/lib/exec.c 21 Jun 2005 14:22:19 -0000
@@ -92,11 +92,8 @@
extern struct btinfo_console btinfo_console;
-int
-exec_netbsd(file, loadaddr, boothowto)
- const char *file;
- physaddr_t loadaddr;
- int boothowto;
+int
+exec_netbsd(const char *file, physaddr_t loadaddr, int boothowto)
{
u_long boot_argv[BOOT_NARGS];
int fd;
@@ -134,7 +131,7 @@
*/
if (xmsmem > extmem)
extmem = xmsmem;
- /*
+ /*
* Get the size of the kernel
*/
marks[MARK_START] = loadaddr;
@@ -147,7 +144,7 @@
loadaddr = xmsalloc(kernsize);
if (!loadaddr)
- return(ENOMEM);
+ return ENOMEM;
}
#endif
marks[MARK_START] = loadaddr;
@@ -206,11 +203,11 @@
BI_ADD(&btinfo_symtab, BTINFO_SYMTAB, sizeof(struct btinfo_symtab));
startprog(marks[MARK_ENTRY], BOOT_NARGS, boot_argv,
- x86_trunc_page(basemem*1024));
+ x86_trunc_page(basemem*1024));
panic("exec returned");
out:
BI_FREE();
bootinfo = 0;
- return (-1);
+ return -1;
}
Index: sys/arch/i386/stand/lib/libi386.h
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/libi386.h,v
retrieving revision 1.19
diff -u -r1.19 libi386.h
--- sys/arch/i386/stand/lib/libi386.h 13 Jun 2005 11:37:41 -0000 1.19
+++ sys/arch/i386/stand/lib/libi386.h 21 Jun 2005 14:22:19 -0000
@@ -68,8 +68,8 @@
char awaitkey(int, int);
/* this is in "user code"! */
-int parsebootfile(const char *, char **, char **, unsigned int *,
- unsigned int *, const char **);
+int parsebootfile(const char *, char **, char **, int *, int *,
+ const char **);
#ifdef XMS
physaddr_t ppbcopy(physaddr_t, physaddr_t, int);
@@ -119,6 +119,8 @@
int int13_extension(int);
struct biosdisk_ext13info;
void int13_getextinfo(int, struct biosdisk_ext13info *);
+int get_harddrives(void);
+
int pcibios_cfgread(unsigned int, int, int *);
int pcibios_cfgwrite(unsigned int, int, int);
int pcibios_finddev(int, int, int, unsigned int *);
Index: sys/lib/libsa/cd9660.c
===================================================================
RCS file: /cvsroot/src/sys/lib/libsa/cd9660.c,v
retrieving revision 1.18
diff -u -r1.18 cd9660.c
--- sys/lib/libsa/cd9660.c 13 Jun 2005 12:06:36 -0000 1.18
+++ sys/lib/libsa/cd9660.c 21 Jun 2005 14:22:21 -0000
@@ -71,7 +71,7 @@
#define PTFIXSZ 8
#define PTSIZE(pp) roundup(PTFIXSZ + isonum_711((pp)->namlen), 2)
-#define cdb2devb(bno) ((bno) * ISO_DEFAULT_BLOCK_SIZE / DEV_BSIZE)
+#define cdb2devb(bno) (bno)
static int pnmatch(const char *, struct ptable_ent *);
static int dirmatch(const char *, struct iso_directory_record *);
--- /dev/null 2005-06-21 23:10:27.000000000 +0900
+++ sys/arch/i386/stand/lib/getbasemem.c 2005-06-20 14:14:27.000000000 +0900
@@ -0,0 +1,28 @@
+/* $NetBSD$ */
+
+/*
+ * Written by Bang Jun-Young, 2005.
+ *
+ * This file is placed in public domain.
+ */
+
+#include <lib/libsa/stand.h>
+
+#include "libi386.h"
+
+/*
+ * Return the size of the base memory in kB.
+ */
+int
+getbasemem(void)
+{
+ int memsize = 0;
+
+ /*
+ * Instead of using int12 which is reported to be buggy on some
+ * BIOSes, read a 16-bit word located in the BIOS data area.
+ */
+ pvbcopy((void *)0x413, &memsize, 2);
+
+ return memsize;
+}
--Boundary-00=_NaCuCN2P1fCtx/a--