kern/158358: [patch] allow /boot/loader to work from an MBR
extended partition
Gyrd Thane Lange
gyrd-se at thanelange.no
Tue Jun 28 01:00:29 UTC 2011
>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 at 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:
More information about the freebsd-bugs
mailing list