From nobody@FreeBSD.org  Tue Jun 28 00:58:16 2011
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id BC6051065670
	for <freebsd-gnats-submit@FreeBSD.org>; 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 <freebsd-gnats-submit@FreeBSD.org>; 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 <freebsd-gnats-submit@FreeBSD.org>; 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 <gyrd-se@thanelange.no>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [patch] allow /boot/loader to work from an MBR extended partition
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         158358
>Category:       kern
>Synopsis:       [loader] [patch] allow /boot/loader to work from an MBR extended partition
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    ae
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jun 28 01:00:20 UTC 2011
>Closed-Date:    Mon Nov 19 13:09:22 UTC 2012
>Last-Modified:  Mon Nov 19 13:09:22 UTC 2012
>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:
State-Changed-From-To: open->patched 
State-Changed-By: ae 
State-Changed-When: Mon Aug 6 08:55:30 UTC 2012 
State-Changed-Why:  
This issue fixed in head/ after r239088. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=158358 
Responsible-Changed-From-To: freebsd-bugs->ae 
Responsible-Changed-By: ae 
Responsible-Changed-When: Wed Oct 17 15:31:57 UTC 2012 
Responsible-Changed-Why:  
Take. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=158358 
State-Changed-From-To: patched->closed 
State-Changed-By: ae 
State-Changed-When: Mon Nov 19 13:08:43 UTC 2012 
State-Changed-Why:  
Fixed in r243243. Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=158358 
>Unformatted:
