From owner-freebsd-bugs@FreeBSD.ORG Tue Jun 28 01:00:29 2011 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C37F310656A5 for ; Tue, 28 Jun 2011 01:00:29 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id E39708FC32 for ; Tue, 28 Jun 2011 01:00:21 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id p5S10LmH039908 for ; Tue, 28 Jun 2011 01:00:21 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id p5S10LKP039907; Tue, 28 Jun 2011 01:00:21 GMT (envelope-from gnats) Resent-Date: Tue, 28 Jun 2011 01:00:21 GMT Resent-Message-Id: <201106280100.p5S10LKP039907@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Gyrd Thane Lange Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BC6051065670 for ; Tue, 28 Jun 2011 00:58:16 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22]) by mx1.freebsd.org (Postfix) with ESMTP id A21598FC08 for ; Tue, 28 Jun 2011 00:58:16 +0000 (UTC) Received: from red.freebsd.org (localhost [127.0.0.1]) by red.freebsd.org (8.14.4/8.14.4) with ESMTP id p5S0wGfb073446 for ; Tue, 28 Jun 2011 00:58:16 GMT (envelope-from nobody@red.freebsd.org) Received: (from nobody@localhost) by red.freebsd.org (8.14.4/8.14.4/Submit) id p5S0wGdA073444; Tue, 28 Jun 2011 00:58:16 GMT (envelope-from nobody) Message-Id: <201106280058.p5S0wGdA073444@red.freebsd.org> Date: Tue, 28 Jun 2011 00:58:16 GMT From: Gyrd Thane Lange To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/158358: [patch] allow /boot/loader to work from an MBR extended partition X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 28 Jun 2011 01:00:29 -0000 >Number: 158358 >Category: kern >Synopsis: [patch] allow /boot/loader to work from an MBR extended partition >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Jun 28 01:00:20 UTC 2011 >Closed-Date: >Last-Modified: >Originator: Gyrd Thane Lange >Release: FreeBSD 9.0-CURRENT amd64 >Organization: >Environment: FreeBSD parvati.thanelange.no 9.0-CURRENT FreeBSD 9.0-CURRENT #7 r221413M: Thu May 5 00:22:25 CEST 2011 root@parvati.thanelange.no:/usr/obj/usr/src/sys/PARVATI amd64 >Description: http://parvati.thanelange.no/freebsd/boot_loader/ The FreeBSD loader has since a very long time ago attempted to work with MBR extended partitions but a simple logical error has prevented it from succeeding: How it is supposed to work. ----- | 1 | ----- | 2 | -- ----- | | | | ----- <- | 5 | ----- | | -- ----- | | | | ----- <- | 6 | ----- | | ----- How /boot/loader (incorrectly) works. ----- | 1 | ----- | 2 | -- ----- | | | | ----- <- | 5 | ----- | 6 | -- ----- | | | | ----- <- | 7 | ----- | 8 | ----- >How-To-Repeat: Install FreeBSD in an MBR extended partition. (It is easily doable using command line tools.) Attempt to boot. Observe that the /boot/loader does not find the desired partition. >Fix: Using the attached patch: patch -d /usr/src/sys/boot/i386/libi386/ < boot_loader.diff Patch is also found here: http://parvati.thanelange.no/freebsd/boot_loader/boot_loader.diff Patch attached with submission follows: --- biosdisk.c.orig 2007-11-13 00:53:43.000000000 +0100 +++ biosdisk.c 2007-12-29 10:35:30.000000000 +0100 @@ -162,7 +162,8 @@ static void bd_closedisk(struct open_disk *od); static int bd_open_mbr(struct open_disk *od, struct i386_devdesc *dev); static int bd_bestslice(struct open_disk *od); -static void bd_checkextended(struct open_disk *od, int slicenum); +static void bd_checkextended(struct open_disk *od, struct dos_partition *dp, + struct dos_partition *primary_dp); static int bd_open_gpt(struct open_disk *od, struct i386_devdesc *dev); static struct gpt_part *bd_best_gptpart(struct open_disk *od); @@ -381,6 +382,13 @@ switch (dp->dp_typ) { case DOSPTYP_386BSD: + if (verbose) + sprintf(line, "%s: BSD %.6dMB (%d - %d)\n", + prefix, dp->dp_size / 2048, + dp->dp_start, dp->dp_start + dp->dp_size); + else + sprintf(line, "%s: BSD\n", prefix); + pager_output(line); bd_printbsdslice(od, (daddr_t)dp->dp_start, prefix, verbose); return; case DOSPTYP_LINSWP: @@ -626,7 +634,7 @@ sizeof(struct dos_partition) * NDOSPART); od->od_nslices = 4; /* extended slices start here */ for (i = 0; i < NDOSPART; i++) - bd_checkextended(od, i); + bd_checkextended(od, &od->od_slicetab[i], &od->od_slicetab[i]); od->od_flags |= BD_PARTTABOK; dptr = &od->od_slicetab[0]; @@ -728,16 +736,12 @@ } static void -bd_checkextended(struct open_disk *od, int slicenum) +bd_checkextended(struct open_disk *od, struct dos_partition *dp, struct dos_partition *primary_dp) { char buf[BIOSDISK_SECSIZE]; - struct dos_partition *dp; - u_int base; - int i, start, end; - - dp = &od->od_slicetab[slicenum]; - start = od->od_nslices; - + int i; + struct dos_partition *base_dp; + if (dp->dp_size == 0) goto done; if (dp->dp_typ != DOSPTYP_EXT) @@ -748,24 +752,22 @@ DEBUG("no magic in extended table"); goto done; } - base = dp->dp_start; + base_dp = dp; dp = (struct dos_partition *)(&buf[DOSPARTOFF]); for (i = 0; i < NDOSPART; i++, dp++) { if (dp->dp_size == 0) continue; if (od->od_nslices == NEXTDOSPART) goto done; - dp->dp_start += base; - bcopy(dp, &od->od_slicetab[od->od_nslices], sizeof(*dp)); - od->od_nslices++; + if (dp->dp_typ == DOSPTYP_EXT) { + dp->dp_start += primary_dp->dp_start; + bd_checkextended(od, dp, primary_dp); + } else { + dp->dp_start += base_dp->dp_start; + bcopy(dp, &od->od_slicetab[od->od_nslices], sizeof(*dp)); + od->od_nslices++; + } } - end = od->od_nslices; - - /* - * now, recursively check the slices we just added - */ - for (i = start; i < end; i++) - bd_checkextended(od, i); done: return; } >Release-Note: >Audit-Trail: >Unformatted: