summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2011-03-08 17:24:32 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2011-03-08 17:24:32 +0000
commit89b8def59d9a3017d87424b789c1b7b9d7dbdbe3 (patch)
tree06c9440fd1aa9cd4d3a8613a3b662b5d063c8010 /sys/arch/i386
parenta0c058adbc7d11b87af5362d9f3f9ef5232e8af6 (diff)
Fix extended partition searching so we don't get lost. The offset
of the next EBR is relative to the start of the extended partition described in the first MBR, not relative to the EBR specifying the offset in its extended partition entry. Clean up installboot -v output. Use daddr64_t for all sector numbers. Not a complete fix, but better than what we had. More tweaks to come. Inspired by a diff and cluebat from uscav on tech@ a few weeks ago. Feedback from matthew@, weingart@. ok deraadt@
Diffstat (limited to 'sys/arch/i386')
-rw-r--r--sys/arch/i386/stand/boot/conf.c4
-rw-r--r--sys/arch/i386/stand/cdboot/conf.c4
-rw-r--r--sys/arch/i386/stand/installboot/installboot.c79
-rw-r--r--sys/arch/i386/stand/libsa/biosdev.c45
-rw-r--r--sys/arch/i386/stand/pxeboot/conf.c4
5 files changed, 79 insertions, 57 deletions
diff --git a/sys/arch/i386/stand/boot/conf.c b/sys/arch/i386/stand/boot/conf.c
index b737e41c236..8c564ea0213 100644
--- a/sys/arch/i386/stand/boot/conf.c
+++ b/sys/arch/i386/stand/boot/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.44 2010/12/06 22:51:45 jasper Exp $ */
+/* $OpenBSD: conf.c,v 1.45 2011/03/08 17:24:31 krw Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -43,7 +43,7 @@
#include <dev/cons.h>
#include "debug.h"
-const char version[] = "3.15";
+const char version[] = "3.16";
int debug = 1;
diff --git a/sys/arch/i386/stand/cdboot/conf.c b/sys/arch/i386/stand/cdboot/conf.c
index 597fb2e4f64..15c11cf01b5 100644
--- a/sys/arch/i386/stand/cdboot/conf.c
+++ b/sys/arch/i386/stand/cdboot/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.16 2010/12/06 22:51:45 jasper Exp $ */
+/* $OpenBSD: conf.c,v 1.17 2011/03/08 17:24:31 krw Exp $ */
/*
* Copyright (c) 2004 Tom Cosgrove
@@ -44,7 +44,7 @@
#include <dev/cons.h>
#include "debug.h"
-const char version[] = "3.15";
+const char version[] = "3.16";
int debug = 1;
#undef _TEST
diff --git a/sys/arch/i386/stand/installboot/installboot.c b/sys/arch/i386/stand/installboot/installboot.c
index 003d5a9cc14..7998ebccae2 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.56 2011/01/23 14:57:08 jsing Exp $ */
+/* $OpenBSD: installboot.c,v 1.57 2011/03/08 17:24:31 krw Exp $ */
/* $NetBSD: installboot.c,v 1.5 1995/11/17 23:23:50 gwr Exp $ */
/*
@@ -103,13 +103,15 @@ static void devread(int, void *, daddr_t, size_t, char *);
static void sym_set_value(struct sym_data *, char *, u_int32_t);
static void pbr_set_symbols(char *, char *, struct sym_data *);
static void usage(void);
-static long findopenbsd(int, struct disklabel *, off_t, int *);
+static daddr64_t findopenbsd(int, struct disklabel *, daddr64_t, int *);
static void write_bootblocks(int devfd, struct disklabel *);
static int sr_volume(int, int *, int *);
static void sr_installboot(int);
static void sr_installpbr(int, int, int);
+static daddr64_t mbr_eoff; /* Offset of the MBR extended partition. */
+
static void
usage(void)
{
@@ -210,10 +212,9 @@ main(int argc, char *argv[])
void
write_bootblocks(int devfd, struct disklabel *dl)
{
- struct stat sb;
- off_t startoff = 0;
- long start = 0;
- int n = 8;
+ struct stat sb;
+ daddr64_t start = 0;
+ int n = 8;
/* Write patched proto bootblock(s) into the superblock. */
if (fstat(devfd, &sb) < 0)
@@ -233,64 +234,76 @@ write_bootblocks(int devfd, struct disklabel *dl)
if (dl->d_type != 0 && dl->d_type != DTYPE_FLOPPY &&
dl->d_type != DTYPE_VND) {
/* Find OpenBSD partition. */
- start = findopenbsd(devfd, dl, (off_t)DOSBBSECTOR, &n);
+ mbr_eoff = 0; /* Offset of MBR extended partition. */
+ start = findopenbsd(devfd, dl, (daddr64_t)DOSBBSECTOR, &n);
if (start == -1)
errx(1, "no OpenBSD partition");
- startoff = (off_t)start * dl->d_secsize;
}
+ if (verbose)
+ fprintf(stderr, "/boot will be written at sector %lld\n",
+ (long long)start);
+
if (!nowrite) {
- if (lseek(devfd, startoff, SEEK_SET) < 0 ||
+ if (lseek(devfd, (off_t)start * dl->d_secsize, SEEK_SET) < 0 ||
write(devfd, protostore, protosize) != protosize)
err(1, "write bootstrap");
}
}
-long
-findopenbsd(int devfd, struct disklabel *dl, off_t mbroff, int *n)
+daddr64_t
+findopenbsd(int devfd, struct disklabel *dl, daddr64_t mbroff, int *n)
{
struct dos_mbr mbr;
struct dos_partition *dp;
- off_t startoff;
- long start;
+ daddr64_t start = -1;
+ int i;
/* Limit the number of recursions */
if (!(*n)--)
return (-1);
+ if (verbose)
+ fprintf(stderr, "%s boot record (%cBR) at sector %lld\n",
+ (mbroff == (off_t)DOSBBSECTOR) ? "master" : "extended",
+ (mbroff == (off_t)DOSBBSECTOR) ? 'M' : 'E',
+ (long long)mbroff);
+
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");
+ err(4, "can't read boot record");
if (mbr.dmbr_sign != DOSMBR_SIGNATURE)
- errx(1, "broken MBR");
+ errx(1, "invalid boot record signature (0x%04X) @ sector %lld",
+ mbr.dmbr_sign, (long long)mbroff);
- for (dp = mbr.dmbr_parts; dp < &mbr.dmbr_parts[NDOSPART];
- dp++) {
+ for (i = 0; i < NDOSPART; i++) {
+ dp = &mbr.dmbr_parts[i];
if (!dp->dp_size)
continue;
+
+ if (verbose)
+ fprintf(stderr,
+ "\tpartition %d: type 0x%02X offset %d size %d\n",
+ i, dp->dp_typ, dp->dp_start, dp->dp_size);
+
if (dp->dp_typ == DOSPTYP_OPENBSD) {
- if (verbose)
- fprintf(stderr,
- "using MBR partition %ld: type 0x%02X offset %d\n",
- (long)(dp - mbr.dmbr_parts),
- dp->dp_typ, dp->dp_start);
- return (dp->dp_start + mbroff);
- } else if (dp->dp_typ == DOSPTYP_EXTEND ||
+ start = (daddr64_t)dp->dp_start + mbroff;
+ break;
+ }
+
+ if (dp->dp_typ == DOSPTYP_EXTEND ||
dp->dp_typ == DOSPTYP_EXTENDL) {
- if (verbose)
- fprintf(stderr,
- "extended partition %ld: type 0x%02X offset %d\n",
- (long)(dp - mbr.dmbr_parts),
- dp->dp_typ, dp->dp_start);
- startoff = (off_t)dp->dp_start + mbroff;
- start = findopenbsd(devfd, dl, startoff, n);
+ mbroff = (daddr64_t)dp->dp_start + mbr_eoff;
+ if (!mbr_eoff)
+ mbr_eoff = (daddr64_t)dp->dp_start;
+ start = findopenbsd(devfd, dl, mbroff, n);
if (start != -1)
- return (start);
+ break;
}
}
- return (-1);
+ return (start);
}
/*
diff --git a/sys/arch/i386/stand/libsa/biosdev.c b/sys/arch/i386/stand/libsa/biosdev.c
index 9f5fa49637d..38fa6e66060 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.77 2010/08/11 13:11:57 deraadt Exp $ */
+/* $OpenBSD: biosdev.c,v 1.78 2011/03/08 17:24:31 krw Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -46,11 +46,13 @@ static int biosdisk_errno(u_int);
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, const char **, int *);
+static daddr64_t findopenbsd(bios_diskinfo_t *, daddr64_t, const char **,
+ int *);
extern int debug;
int bios_bootdev;
int bios_cddev = -1; /* Set by srt0 if coming from CD */
+daddr64_t mbr_eoff; /* Offset of MBR extended partition. */
#if 0
struct biosdisk {
@@ -344,13 +346,13 @@ 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 mbroff, const char **err, int *n)
+static daddr64_t
+findopenbsd(bios_diskinfo_t *bd, daddr64_t mbroff, const char **err, int *n)
{
- int error, i;
struct dos_mbr mbr;
struct dos_partition *dp;
- daddr_t off;
+ daddr64_t start = -1;
+ int error, i;
/* Limit the number of recursions */
if (!(*n)--) {
@@ -385,22 +387,28 @@ findopenbsd(bios_diskinfo_t *bd, daddr_t mbroff, const char **err, int *n)
dp->dp_start, dp->dp_start);
#endif
if (dp->dp_typ == DOSPTYP_OPENBSD) {
- return (dp->dp_start + mbroff);
- } else if (dp->dp_typ == DOSPTYP_EXTEND ||
+ start = (daddr64_t)dp->dp_start + mbroff;
+ break;
+ }
+
+ if (dp->dp_typ == DOSPTYP_EXTEND ||
dp->dp_typ == DOSPTYP_EXTENDL) {
- off = findopenbsd(bd, dp->dp_start + mbroff, err, n);
- if (off != -1)
- return (off);
+ mbroff = (daddr64_t)dp->dp_start + mbr_eoff;
+ if (!mbr_eoff)
+ mbr_eoff = (daddr64_t)dp->dp_start;
+ start = findopenbsd(bd, mbroff, err, n);
+ if (start != -1)
+ break;
}
}
- return (-1);
+ return (start);
}
const char *
bios_getdisklabel(bios_diskinfo_t *bd, struct disklabel *label)
{
- daddr_t off = 0;
+ daddr64_t start = 0;
char *buf;
const char *err = NULL;
int error;
@@ -413,23 +421,24 @@ bios_getdisklabel(bios_diskinfo_t *bd, struct disklabel *label)
/* MBR is a harddisk thing */
if (bd->bios_number & 0x80) {
- off = findopenbsd(bd, DOSBBSECTOR, &err, &n);
- if (off == -1) {
+ mbr_eoff = 0;
+ start = findopenbsd(bd, (daddr64_t)DOSBBSECTOR, &err, &n);
+ if (start == -1) {
if (err != NULL)
return (err);
return "no OpenBSD partition\n";
}
}
- off = LABELSECTOR + off;
+ start = LABELSECTOR + start;
/* Load BSD disklabel */
buf = alloca(DEV_BSIZE);
#ifdef BIOS_DEBUG
if (debug)
- printf("loading disklabel @ %u\n", off);
+ printf("loading disklabel @ %lld\n", start);
#endif
/* read disklabel */
- error = biosd_io(F_READ, bd, off, 1, buf);
+ error = biosd_io(F_READ, bd, (daddr_t)start, 1, buf);
if (error)
return "failed to read disklabel";
diff --git a/sys/arch/i386/stand/pxeboot/conf.c b/sys/arch/i386/stand/pxeboot/conf.c
index 204950d0bc1..c53482fcbba 100644
--- a/sys/arch/i386/stand/pxeboot/conf.c
+++ b/sys/arch/i386/stand/pxeboot/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.21 2010/12/06 22:51:46 jasper Exp $ */
+/* $OpenBSD: conf.c,v 1.22 2011/03/08 17:24:31 krw Exp $ */
/*
* Copyright (c) 2004 Tom Cosgrove
@@ -46,7 +46,7 @@
#include "pxeboot.h"
#include "pxe_net.h"
-const char version[] = "3.15";
+const char version[] = "3.16";
int debug = 1;
#undef _TEST