--- src/sys/boot/i386/libi386/biosdisk.c.org 2010-12-22 02:09:25.000000000 +0900 +++ src/sys/boot/i386/libi386/biosdisk.c 2011-07-18 16:39:40.000000000 +0900 @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/boot/i386/libi386/biosdisk.c,v 1.62.2.2.4.1 2010/12/21 17:09:25 kensmith Exp $"); +__FBSDID("$FreeBSD: src/sys/boot/i386/libi386/biosdisk.c,v 1.62.2.2.4.1 2010/12/21 17:09:25 kensmith Exp $"); /* * BIOS disk device handling. @@ -100,6 +100,7 @@ struct open_disk { struct disklabel mbr_disklabel; int mbr_nslices; /* slice count */ struct dos_partition mbr_slicetab[NEXTDOSPART]; + u_int mbr_extbase; } _mbr; #ifdef LOADER_GPT_SUPPORT struct { @@ -113,6 +114,7 @@ struct open_disk { #define od_disklabel _data._mbr.mbr_disklabel #define od_nslices _data._mbr.mbr_nslices #define od_slicetab _data._mbr.mbr_slicetab +#define od_extbase _data._mbr.mbr_extbase #ifdef LOADER_GPT_SUPPORT #define od_nparts _data._gpt.gpt_nparts #define od_partitions _data._gpt.gpt_partitions @@ -431,6 +433,7 @@ bd_printslice(struct open_disk *od, stru break; case 0x00: /* unused partition */ case DOSPTYP_EXT: + case DOSPTYP_EXTLBA: return; case 0x01: sprintf(line, "%s: FAT-12%s\n", prefix, stats); @@ -612,6 +615,7 @@ bd_open_mbr(struct open_disk *od, struct * Find the slice in the DOS slice table. */ od->od_nslices = 0; + od->od_extbase = 0; if (bd_read(od, 0, 1, buf)) { DEBUG("error reading MBR"); return (EIO); @@ -751,7 +755,7 @@ bd_checkextended(struct open_disk *od, i if (dp->dp_size == 0) goto done; - if (dp->dp_typ != DOSPTYP_EXT) + if ((dp->dp_typ != DOSPTYP_EXT) && (dp->dp_typ != DOSPTYP_EXTLBA)) goto done; if (bd_read(od, (daddr_t)dp->dp_start, 1, buf)) goto done; @@ -759,6 +763,8 @@ bd_checkextended(struct open_disk *od, i DEBUG("no magic in extended table"); goto done; } + if (od->od_extbase == 0) + od->od_extbase = dp->dp_start; base = dp->dp_start; dp = (struct dos_partition *)(&buf[DOSPARTOFF]); for (i = 0; i < NDOSPART; i++, dp++) { @@ -766,7 +772,10 @@ bd_checkextended(struct open_disk *od, i continue; if (od->od_nslices == NEXTDOSPART) goto done; - dp->dp_start += base; + if ((dp->dp_typ == DOSPTYP_EXT) || (dp->dp_typ == DOSPTYP_EXTLBA)) + dp->dp_start += od->od_extbase; + else + dp->dp_start += base; bcopy(dp, &od->od_slicetab[od->od_nslices], sizeof(*dp)); od->od_nslices++; }