aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Soltys <soltys@ziu.info>2010-08-25 01:28:50 +0200
committerMichal Soltys <soltys@ziu.info>2010-09-28 09:32:52 +0200
commit1c1f14dc77b5b361333a7e790eed3206526fb26d (patch)
tree4335f8d119cff008aca742ab6f80bd78538ca1cd
parentcc5c2ccd0b4acb64db011459b90574ec33f5284b (diff)
downloadsyslinux-1c1f14dc77b5b361333a7e790eed3206526fb26d.tar.gz
syslinux-1c1f14dc77b5b361333a7e790eed3206526fb26d.tar.xz
syslinux-1c1f14dc77b5b361333a7e790eed3206526fb26d.zip
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@ziu.info>
-rw-r--r--com32/chain/chain.c25
-rw-r--r--com32/chain/partiter.c31
-rw-r--r--com32/chain/partiter.h3
3 files changed, 27 insertions, 32 deletions
diff --git a/com32/chain/chain.c b/com32/chain/chain.c
index 19351f4a..12372aab 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 0fc542b6..f76359cb 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 694969ab..971d388e 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;