[syslinux:master] chain: adjust 'mbrchs' calculations, adjust partitier

syslinux-bot for Michal Soltys soltys at ziu.info
Mon Mar 26 15:03:16 PDT 2012


Commit-ID:  1c1f14dc77b5b361333a7e790eed3206526fb26d
Gitweb:     http://www.syslinux.org/commit/1c1f14dc77b5b361333a7e790eed3206526fb26d
Author:     Michal Soltys <soltys at ziu.info>
AuthorDate: Wed, 25 Aug 2010 01:28:50 +0200
Committer:  Michal Soltys <soltys at ziu.info>
CommitDate: Tue, 28 Sep 2010 09:32:52 +0200

chain: adjust 'mbrchs' calculations, adjust partitier

It seems that chs values in extended partitions are expected to provide
absolute positions. Previously these values were calculated directly
from ebr lba values.

Partiter now provides cebr_lba and ebr_lba that hold absolute values
of current and next ebr.

Signed-off-by: Michal Soltys <soltys at ziu.info>

---
 com32/chain/chain.c    |   25 +++++++++++++------------
 com32/chain/partiter.c |   31 ++++++++++++-------------------
 com32/chain/partiter.h |    3 ++-
 3 files changed, 27 insertions(+), 32 deletions(-)

diff --git a/com32/chain/chain.c b/com32/chain/chain.c
index 19351f4..12372aa 100644
--- a/com32/chain/chain.c
+++ b/com32/chain/chain.c
@@ -357,7 +357,8 @@ static int pem_sethide(struct disk_dos_part_entry *dp, int midx, int idx)
 }
 
 static int pem_setchs(const struct disk_info *di,
-		     struct disk_dos_part_entry *dp)
+		     struct disk_dos_part_entry *dp,
+		     uint32_t lba1)
 {
     uint32_t ochs1, ochs2;
 
@@ -365,11 +366,11 @@ static int pem_setchs(const struct disk_info *di,
     ochs2 = *(uint32_t *)dp->end;
 
     *(uint32_t *)dp->start =
-	lba2chs(di, dp->start_lba) |
+	lba2chs(di, lba1) |
 	(*(uint32_t *)dp->start & 0xFF000000);
 
     *(uint32_t *)dp->end =
-	lba2chs(di, dp->start_lba + dp->length - 1) |
+	lba2chs(di, lba1 + dp->length - 1) |
 	(*(uint32_t *)dp->end & 0xFF000000);
 
     return
@@ -377,10 +378,10 @@ static int pem_setchs(const struct disk_info *di,
 	*(uint32_t *)dp->end != ochs2;
 }
 
-static int pe_mangle(const struct part_iter *_iter)
+static int pe_mangle(struct part_iter *_iter)
 {
     int wb = 0, werr = 0;
-    uint32_t mbr_lba = 0;
+    uint32_t cebr_lba = 0;
     struct part_iter *iter = NULL;
     struct disk_dos_part_entry *dp;
     struct disk_dos_mbr mbr;
@@ -403,13 +404,13 @@ static int pe_mangle(const struct part_iter *_iter)
 	ridx = iter->rawindex;
 	if (ridx > 4) {
 	    if (opt.hide < 2 && !opt.mbrchs)
-		break;
+		break;	/* don't walk unnecessarily */
 	    if (wb && !werr) {
-		werr |= disk_write_verify_sector(&_iter->di, mbr_lba, &mbr);
+		werr |= disk_write_sector(&iter->di, cebr_lba, &mbr);
 		wb = false;
 	    }
 	    memcpy(&mbr, iter->data, sizeof(struct disk_dos_mbr));
-	    mbr_lba = iter->sub.dos.mbr_lba;
+	    cebr_lba = iter->sub.dos.cebr_lba;
 	    dp = mbr.table;
 	} else
 	    dp = mbr.table + ridx - 1;
@@ -422,20 +423,20 @@ static int pe_mangle(const struct part_iter *_iter)
 	    }
 	}
 	if (opt.mbrchs) {
-	    wb |= pem_setchs(&_iter->di, dp);
+	    wb |= pem_setchs(&iter->di, dp, (uint32_t)iter->start_lba);
 	    if (ridx > 4)
-		wb |= pem_setchs(&_iter->di, mbr.table + 1);
+		wb |= pem_setchs(&iter->di, mbr.table + 1, iter->sub.dos.ebr_lba);
 	}
     }
     /* last write */
     if (wb && !werr)
-	werr |= disk_write_verify_sector(&_iter->di, mbr_lba, &mbr);
+	werr |= disk_write_sector(&_iter->di, cebr_lba, &mbr);
 
 bail:
     pi_del(&iter);
     if (werr)
 	error("WARNING: failed to write E/MBR for partition\n"
-	      "mangling options ('hide[all]', 'mbrchs')\n");
+	      "mangling options ('hide[all]', 'mbrchs').\n");
     return 0;
 }
 
diff --git a/com32/chain/partiter.c b/com32/chain/partiter.c
index 0fc542b..f76359c 100644
--- a/com32/chain/partiter.c
+++ b/com32/chain/partiter.c
@@ -369,6 +369,9 @@ static int prep_base_ebr(struct part_iter *iter)
 	iter->sub.dos.ebr_start = 0;
 	iter->sub.dos.ebr_size = iter->sub.dos.bebr_size;
 
+	iter->sub.dos.cebr_lba = 0;
+	iter->sub.dos.ebr_lba = iter->sub.dos.bebr_start;
+
 	iter->index0--;
     }
     return 0;
@@ -378,23 +381,14 @@ static int pi_dos_next_ebr(struct part_iter *iter, uint32_t *lba,
 			    struct disk_dos_part_entry **_dp)
 {
     struct disk_dos_part_entry *dp;
-    uint32_t abs_ebr;
 
     if (prep_base_ebr(iter))
 	return -1;
 
-#if 0
-    if(++iter->index0 >= 1024)
-	/* that's one paranoid upper bound */
-	goto bail;
-#endif
-    while (++iter->index0 < 1024 && iter->sub.dos.ebr_size) {
-
-	abs_ebr = iter->sub.dos.bebr_start + iter->sub.dos.ebr_start;
-
-	/* load ebr for current iteration */
+    while (++iter->index0 < 1024 && iter->sub.dos.ebr_lba) {
 	free(iter->data);
-	if (!(iter->data = disk_read_sectors(&iter->di, abs_ebr, 1))) {
+	if (!(iter->data =
+		    disk_read_sectors(&iter->di, iter->sub.dos.ebr_lba, 1))) {
 	    error("Couldn't load EBR.\n");
 	    return -1;
 	}
@@ -402,23 +396,26 @@ static int pi_dos_next_ebr(struct part_iter *iter, uint32_t *lba,
 	if (notsane_logical(iter) || notsane_extended(iter))
 	    return -1;
 
-	iter->sub.dos.mbr_lba = abs_ebr;
 	dp = ((struct disk_dos_mbr *)iter->data)->table;
-	abs_ebr += dp[0].start_lba;
+
+	iter->sub.dos.cebr_lba = iter->sub.dos.ebr_lba;
 
 	/* setup next frame values */
 	if (dp[1].ostype) {
 	    iter->sub.dos.ebr_start = dp[1].start_lba;
 	    iter->sub.dos.ebr_size = dp[1].length;
+	    iter->sub.dos.ebr_lba = iter->sub.dos.bebr_start + dp[1].start_lba;
 	} else {
+	    iter->sub.dos.ebr_start = 0;
 	    iter->sub.dos.ebr_size = 0;
+	    iter->sub.dos.ebr_lba = 0;
 	}
 
 	if (!dp[0].ostype)
 	    iter->sub.dos.skipcnt++;
 
 	if (dp[0].ostype || iter->stepall) {
-	    *lba = abs_ebr;
+	    *lba = iter->sub.dos.cebr_lba + dp[0].start_lba;
 	    *_dp = dp;
 	    return 0;
 	}
@@ -430,10 +427,6 @@ static int pi_dos_next_ebr(struct part_iter *iter, uint32_t *lba,
 	 * this place.
 	 */
     }
-#if 0
-    return 0;
-bail:
-#endif
     return -1;
 }
 
diff --git a/com32/chain/partiter.h b/com32/chain/partiter.h
index 694969a..971d388 100644
--- a/com32/chain/partiter.h
+++ b/com32/chain/partiter.h
@@ -64,7 +64,8 @@ struct part_iter {
     union _sub {
 	struct _dos {
 	    uint32_t disk_sig;
-	    uint32_t mbr_lba;
+	    uint32_t ebr_lba;
+	    uint32_t cebr_lba;
 	    /* internal */
 	    uint32_t ebr_start;
 	    uint32_t ebr_size;


More information about the Syslinux-commits mailing list