diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2011-03-08 17:24:32 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2011-03-08 17:24:32 +0000 |
commit | 89b8def59d9a3017d87424b789c1b7b9d7dbdbe3 (patch) | |
tree | 06c9440fd1aa9cd4d3a8613a3b662b5d063c8010 /sys/arch/amd64/stand/libsa | |
parent | a0c058adbc7d11b87af5362d9f3f9ef5232e8af6 (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/amd64/stand/libsa')
-rw-r--r-- | sys/arch/amd64/stand/libsa/biosdev.c | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/sys/arch/amd64/stand/libsa/biosdev.c b/sys/arch/amd64/stand/libsa/biosdev.c index e4185114881..e25c7896ff4 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.9 2010/08/11 13:11:59 deraadt Exp $ */ +/* $OpenBSD: biosdev.c,v 1.10 2011/03/08 17:24:31 krw Exp $ */ /* * Copyright (c) 1996 Michael Shalayeff @@ -45,11 +45,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 the MBR extended partition. */ #if 0 struct biosdisk { @@ -341,13 +343,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)--) { @@ -382,22 +384,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; @@ -410,14 +418,15 @@ 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); @@ -426,7 +435,7 @@ bios_getdisklabel(bios_diskinfo_t *bd, struct disklabel *label) printf("loading disklabel @ %u\n", off); #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"); |