diff options
author | Michal Soltys <soltys@ziu.info> | 2010-08-25 01:28:50 +0200 |
---|---|---|
committer | Michal Soltys <soltys@ziu.info> | 2010-09-28 09:32:52 +0200 |
commit | 1c1f14dc77b5b361333a7e790eed3206526fb26d (patch) | |
tree | 4335f8d119cff008aca742ab6f80bd78538ca1cd | |
parent | cc5c2ccd0b4acb64db011459b90574ec33f5284b (diff) | |
download | syslinux-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.c | 25 | ||||
-rw-r--r-- | com32/chain/partiter.c | 31 | ||||
-rw-r--r-- | 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 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; |