summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2008-08-04 15:58:14 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2008-08-04 15:58:14 +0000
commita9ab805b1ac0b429c1e21ef9951792f773c4cde6 (patch)
tree6565e324559e8dc27dc336b1bfbf2c21f5c3f7bf
parent222b13f8193cd311de104a63752b6aee24d6d8b3 (diff)
fix extended partition support by handling chained EBRs correctly
(using a recursion limit). now OpenBSD can be installed in a subsequent DOS/Linux-compatible extended partition. ok krw@ deraadt@
-rw-r--r--sbin/disklabel/disklabel.c14
-rw-r--r--sys/arch/amd64/stand/installboot/installboot.c15
-rw-r--r--sys/arch/amd64/stand/libsa/biosdev.c27
-rw-r--r--sys/arch/i386/stand/installboot/installboot.c15
-rw-r--r--sys/arch/i386/stand/libsa/biosdev.c27
5 files changed, 45 insertions, 53 deletions
diff --git a/sbin/disklabel/disklabel.c b/sbin/disklabel/disklabel.c
index 7c287a3cbcb..abc88b92731 100644
--- a/sbin/disklabel/disklabel.c
+++ b/sbin/disklabel/disklabel.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disklabel.c,v 1.133 2008/07/10 00:21:39 krw Exp $ */
+/* $OpenBSD: disklabel.c,v 1.134 2008/08/04 15:58:13 reyk Exp $ */
/*
* Copyright (c) 1987, 1993
@@ -39,7 +39,7 @@ static const char copyright[] =
#endif /* not lint */
#ifndef lint
-static const char rcsid[] = "$OpenBSD: disklabel.c,v 1.133 2008/07/10 00:21:39 krw Exp $";
+static const char rcsid[] = "$OpenBSD: disklabel.c,v 1.134 2008/08/04 15:58:13 reyk Exp $";
#endif /* not lint */
#include <sys/param.h>
@@ -579,19 +579,19 @@ findopenbsd(int f, off_t mbroff, struct dos_partition **first, int *n)
"type %02X start %u size %u\n",
part, dp[part].dp_typ,
letoh32(dp[part].dp_start), letoh32(dp[part].dp_size));
+ dp[part].dp_start =
+ htole32((off_t)letoh32(dp[part].dp_start) + mbroff);
return (&dp[part]);
+ case DOSPTYP_EXTEND:
case DOSPTYP_EXTENDL:
fprintf(stderr, "# Extended partition %d: "
"type %02X start %u size %u\n",
part, dp[part].dp_typ,
letoh32(dp[part].dp_start), letoh32(dp[part].dp_size));
- start = letoh32(dp[part].dp_start);
+ start = letoh32(dp[part].dp_start) + mbroff;
p = findopenbsd(f, start, NULL, n);
- if (p != NULL) {
- p->dp_start =
- htole32(letoh32(p->dp_start) + start);
+ if (p != NULL)
return (p);
- }
break;
}
}
diff --git a/sys/arch/amd64/stand/installboot/installboot.c b/sys/arch/amd64/stand/installboot/installboot.c
index 88f134a0094..fb0e95ffce0 100644
--- a/sys/arch/amd64/stand/installboot/installboot.c
+++ b/sys/arch/amd64/stand/installboot/installboot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: installboot.c,v 1.9 2008/06/25 15:26:44 reyk Exp $ */
+/* $OpenBSD: installboot.c,v 1.10 2008/08/04 15:58:13 reyk Exp $ */
/* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */
/*
@@ -231,7 +231,7 @@ findopenbsd(int devfd, struct disklabel *dl, off_t mbroff, int *n)
if (!(*n)--)
return (-1);
- if (lseek(devfd, mbroff, SEEK_SET) < 0 ||
+ if (lseek(devfd, mbroff * dl->d_secsize, SEEK_SET) < 0 ||
read(devfd, &mbr, sizeof(mbr)) != sizeof(mbr))
err(4, "can't read master boot record");
@@ -242,14 +242,13 @@ findopenbsd(int devfd, struct disklabel *dl, off_t mbroff, int *n)
dp++) {
if (!dp->dp_size)
continue;
- startoff = (off_t)dp->dp_start * dl->d_secsize;
if (dp->dp_typ == DOSPTYP_OPENBSD) {
fprintf(stderr, "using MBR partition %ld: "
"type %d (0x%02x) offset %d (0x%x)\n",
(long)(dp - mbr.dmbr_parts),
dp->dp_typ, dp->dp_typ,
dp->dp_start, dp->dp_start);
- break;
+ return (dp->dp_start + mbroff);
} else if (dp->dp_typ == DOSPTYP_EXTEND ||
dp->dp_typ == DOSPTYP_EXTENDL) {
fprintf(stderr, "extended partition %ld: "
@@ -257,16 +256,14 @@ findopenbsd(int devfd, struct disklabel *dl, off_t mbroff, int *n)
(long)(dp - mbr.dmbr_parts),
dp->dp_typ, dp->dp_typ,
dp->dp_start, dp->dp_start);
+ startoff = (off_t)dp->dp_start + mbroff;
start = findopenbsd(devfd, dl, startoff, n);
if (start != -1)
- return (dp->dp_start + start);
+ return (start);
}
}
- /* Don't check for old part number, that is ;-p */
- if (dp >= &mbr.dmbr_parts[NDOSPART])
- return (-1);
- return (dp->dp_start);
+ return (-1);
}
/*
diff --git a/sys/arch/amd64/stand/libsa/biosdev.c b/sys/arch/amd64/stand/libsa/biosdev.c
index 7358eab09f6..ad5075e324f 100644
--- a/sys/arch/amd64/stand/libsa/biosdev.c
+++ b/sys/arch/amd64/stand/libsa/biosdev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: biosdev.c,v 1.6 2008/06/25 15:32:18 reyk Exp $ */
+/* $OpenBSD: biosdev.c,v 1.7 2008/08/04 15:58:13 reyk Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -45,8 +45,7 @@ static int biosdisk_errno(u_int);
static int CHS_rw (int, int, int, int, int, int, void *);
static int EDD_rw (int, int, u_int64_t, u_int32_t, void *);
-static daddr_t findopenbsd(bios_diskinfo_t *, daddr_t, daddr_t *,
- const char **, int *);
+static daddr_t findopenbsd(bios_diskinfo_t *, daddr_t, const char **, int *);
extern int debug;
int bios_bootdev;
@@ -343,8 +342,7 @@ biosd_io(int rw, bios_diskinfo_t *bd, daddr_t off, int nsect, void *buf)
* Try to read the bsd label on the given BIOS device
*/
static daddr_t
-findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err,
- int *n)
+findopenbsd(bios_diskinfo_t *bd, daddr_t off, const char **err, int *n)
{
int error, i;
struct dos_mbr mbr;
@@ -370,7 +368,7 @@ findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err,
}
/* Search for OpenBSD partition */
- for (off = 0, i = 0; off == 0 && i < NDOSPART; i++) {
+ for (i = 0; i < NDOSPART; i++) {
dp = &mbr.dmbr_parts[i];
#ifdef BIOS_DEBUG
if (debug)
@@ -380,13 +378,14 @@ findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err,
dp->dp_typ, dp->dp_typ,
dp->dp_start, dp->dp_start);
#endif
- if (dp->dp_typ == DOSPTYP_OPENBSD)
- off = dp->dp_start;
- else if (dp->dp_typ == DOSPTYP_EXTEND ||
+ if (dp->dp_typ == DOSPTYP_OPENBSD) {
+ off = dp->dp_start + off;
+ break;
+ } else if (dp->dp_typ == DOSPTYP_EXTEND ||
dp->dp_typ == DOSPTYP_EXTENDL) {
- off = findopenbsd(bd, dp->dp_start, roff, err, n);
+ off = findopenbsd(bd, dp->dp_start + off, err, n);
if (off != 0)
- *roff = dp->dp_start;
+ break;
}
}
@@ -407,7 +406,7 @@ findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err,
const char *
bios_getdisklabel(bios_diskinfo_t *bd, struct disklabel *label)
{
- daddr_t off = 0, roff = 0;
+ daddr_t off = 0;
char *buf;
const char *err = NULL;
int error;
@@ -420,14 +419,14 @@ bios_getdisklabel(bios_diskinfo_t *bd, struct disklabel *label)
/* MBR is a harddisk thing */
if (bd->bios_number & 0x80) {
- off = findopenbsd(bd, DOSBBSECTOR, &roff, &err, &n);
+ off = findopenbsd(bd, DOSBBSECTOR, &err, &n);
if (off == 0) {
if (err != NULL)
return (err);
return "no OpenBSD partition\n";
}
}
- off = LABELSECTOR + off + roff;
+ off = LABELSECTOR + off;
/* Load BSD disklabel */
buf = alloca(DEV_BSIZE);
diff --git a/sys/arch/i386/stand/installboot/installboot.c b/sys/arch/i386/stand/installboot/installboot.c
index d0a450147a1..1658d05c0a2 100644
--- a/sys/arch/i386/stand/installboot/installboot.c
+++ b/sys/arch/i386/stand/installboot/installboot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: installboot.c,v 1.52 2008/06/25 15:26:44 reyk Exp $ */
+/* $OpenBSD: installboot.c,v 1.53 2008/08/04 15:58:13 reyk Exp $ */
/* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */
/*
@@ -227,7 +227,7 @@ findopenbsd(int devfd, struct disklabel *dl, off_t mbroff, int *n)
if (!(*n)--)
return (-1);
- if (lseek(devfd, mbroff, SEEK_SET) < 0 ||
+ if (lseek(devfd, mbroff * dl->d_secsize, SEEK_SET) < 0 ||
read(devfd, &mbr, sizeof(mbr)) != sizeof(mbr))
err(4, "can't read master boot record");
@@ -238,14 +238,13 @@ findopenbsd(int devfd, struct disklabel *dl, off_t mbroff, int *n)
dp++) {
if (!dp->dp_size)
continue;
- startoff = (off_t)dp->dp_start * dl->d_secsize;
if (dp->dp_typ == DOSPTYP_OPENBSD) {
fprintf(stderr, "using MBR partition %ld: "
"type %d (0x%02x) offset %d (0x%x)\n",
(long)(dp - mbr.dmbr_parts),
dp->dp_typ, dp->dp_typ,
dp->dp_start, dp->dp_start);
- break;
+ return (dp->dp_start + mbroff);
} else if (dp->dp_typ == DOSPTYP_EXTEND ||
dp->dp_typ == DOSPTYP_EXTENDL) {
fprintf(stderr, "extended partition %ld: "
@@ -253,16 +252,14 @@ findopenbsd(int devfd, struct disklabel *dl, off_t mbroff, int *n)
(long)(dp - mbr.dmbr_parts),
dp->dp_typ, dp->dp_typ,
dp->dp_start, dp->dp_start);
+ startoff = (off_t)dp->dp_start + mbroff;
start = findopenbsd(devfd, dl, startoff, n);
if (start != -1)
- return (dp->dp_start + start);
+ return (start);
}
}
- /* Don't check for old part number, that is ;-p */
- if (dp >= &mbr.dmbr_parts[NDOSPART])
- return (-1);
- return (dp->dp_start);
+ return (-1);
}
/*
diff --git a/sys/arch/i386/stand/libsa/biosdev.c b/sys/arch/i386/stand/libsa/biosdev.c
index 2b8220225ac..3ccc01258cd 100644
--- a/sys/arch/i386/stand/libsa/biosdev.c
+++ b/sys/arch/i386/stand/libsa/biosdev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: biosdev.c,v 1.74 2008/06/25 15:32:18 reyk Exp $ */
+/* $OpenBSD: biosdev.c,v 1.75 2008/08/04 15:58:13 reyk Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -46,8 +46,7 @@ static int biosdisk_errno(u_int);
static int CHS_rw (int, int, int, int, int, int, void *);
static int EDD_rw (int, int, u_int64_t, u_int32_t, void *);
-static daddr_t findopenbsd(bios_diskinfo_t *, daddr_t, daddr_t *,
- const char **, int *);
+static daddr_t findopenbsd(bios_diskinfo_t *, daddr_t, const char **, int *);
extern int debug;
int bios_bootdev;
@@ -346,8 +345,7 @@ biosd_io(int rw, bios_diskinfo_t *bd, daddr_t off, int nsect, void *buf)
* Try to read the bsd label on the given BIOS device
*/
static daddr_t
-findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err,
- int *n)
+findopenbsd(bios_diskinfo_t *bd, daddr_t off, const char **err, int *n)
{
int error, i;
struct dos_mbr mbr;
@@ -373,7 +371,7 @@ findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err,
}
/* Search for OpenBSD partition */
- for (off = 0, i = 0; off == 0 && i < NDOSPART; i++) {
+ for (i = 0; i < NDOSPART; i++) {
dp = &mbr.dmbr_parts[i];
#ifdef BIOS_DEBUG
if (debug)
@@ -383,13 +381,14 @@ findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err,
dp->dp_typ, dp->dp_typ,
dp->dp_start, dp->dp_start);
#endif
- if (dp->dp_typ == DOSPTYP_OPENBSD)
- off = dp->dp_start;
- else if (dp->dp_typ == DOSPTYP_EXTEND ||
+ if (dp->dp_typ == DOSPTYP_OPENBSD) {
+ off = dp->dp_start + off;
+ break;
+ } else if (dp->dp_typ == DOSPTYP_EXTEND ||
dp->dp_typ == DOSPTYP_EXTENDL) {
- off = findopenbsd(bd, dp->dp_start, roff, err, n);
+ off = findopenbsd(bd, dp->dp_start + off, err, n);
if (off != 0)
- *roff = dp->dp_start;
+ break;
}
}
@@ -410,7 +409,7 @@ findopenbsd(bios_diskinfo_t *bd, daddr_t off, daddr_t *roff, const char **err,
const char *
bios_getdisklabel(bios_diskinfo_t *bd, struct disklabel *label)
{
- daddr_t off = 0, roff = 0;
+ daddr_t off = 0;
char *buf;
const char *err = NULL;
int error;
@@ -423,14 +422,14 @@ bios_getdisklabel(bios_diskinfo_t *bd, struct disklabel *label)
/* MBR is a harddisk thing */
if (bd->bios_number & 0x80) {
- off = findopenbsd(bd, DOSBBSECTOR, &roff, &err, &n);
+ off = findopenbsd(bd, DOSBBSECTOR, &err, &n);
if (off == 0) {
if (err != NULL)
return (err);
return "no OpenBSD partition\n";
}
}
- off = LABELSECTOR + off + roff;
+ off = LABELSECTOR + off;
/* Load BSD disklabel */
buf = alloca(DEV_BSIZE);