From 81f86009696b5c7eff76e1981e967367235c5f7c Mon Sep 17 00:00:00 2001 From: Michal Soltys Date: Tue, 28 Sep 2010 19:57:28 +0200 Subject: [PATCH] com32/chain: utility's lba2chs update This patch adds 3 modes of operation to lba2chs: l2c_cnul - strict cylinder mode, using at most the value returned by 13h/48h or 13h/08h l2c_cadd - allow using 1 cylinder more. Only if cylinders are less than 1024 and total drive's lba size is not on a cylinder boundary. l2c_max - allow using any cylinder number. Modes have effect only if CHS geometry (cbios) is valid. chain.c uses l2c_cadd. Signed-off-by: Michal Soltys --- com32/chain/Makefile | 4 +--- com32/chain/chain.c | 26 +++++++++++++++----------- com32/chain/mangle.c | 4 ++-- com32/chain/utility.c | 12 ++++++++---- com32/chain/utility.h | 6 +++++- 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/com32/chain/Makefile b/com32/chain/Makefile index 36710ff..a5602d9 100644 --- a/com32/chain/Makefile +++ b/com32/chain/Makefile @@ -16,8 +16,6 @@ topdir = ../.. include ../MCONFIG OBJS = chain.o partiter.o utility.o options.o mangle.o -#GCCEXTRA = -DDEBUG -#GCCEXTRA += -Wextra -Wconversion -pedantic -Wno-error all: chain.c32 @@ -25,7 +23,7 @@ chain.elf: $(OBJS) $(LIBS) $(C_LIBS) $(LD) $(LDFLAGS) -o $@ $^ %.o: %.c - $(CC) $(MAKEDEPS) $(CFLAGS) $(GCCEXTRA) -c -o $@ $< + $(CC) $(MAKEDEPS) $(CFLAGS) $(CHAINEXTOPT) -c -o $@ $< tidy dist: rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp diff --git a/com32/chain/chain.c b/com32/chain/chain.c index de9e0ec..d33da6a 100644 --- a/com32/chain/chain.c +++ b/com32/chain/chain.c @@ -366,11 +366,11 @@ static int pem_setchs(const struct disk_info *di, ochs2 = *(uint32_t *)dp->end; *(uint32_t *)dp->start = - lba2chs(di, lba1) | + lba2chs(di, lba1, l2c_cadd) | (*(uint32_t *)dp->start & 0xFF000000); *(uint32_t *)dp->end = - lba2chs(di, lba1 + dp->length - 1) | + lba2chs(di, lba1 + dp->length - 1, l2c_cadd) | (*(uint32_t *)dp->end & 0xFF000000); return @@ -406,7 +406,7 @@ static int pentry_mangle(struct part_iter *_iter) if (opt.hide < 2 && !opt.mbrchs) break; /* don't walk unnecessarily */ if (wb && !werr) { - werr |= disk_write_sector(&iter->di, cebr_lba, &mbr); + werr |= disk_write_sectors(&iter->di, cebr_lba, &mbr, 1); wb = false; } memcpy(&mbr, iter->data, sizeof(struct disk_dos_mbr)); @@ -430,7 +430,7 @@ static int pentry_mangle(struct part_iter *_iter) } /* last write */ if (wb && !werr) - werr |= disk_write_sector(&_iter->di, cebr_lba, &mbr); + werr |= disk_write_sectors(&_iter->di, cebr_lba, &mbr, 1); bail: pi_del(&iter); @@ -572,8 +572,8 @@ static int setup_handover(const struct part_iter *iter, error("Could not build GPT hand-over record!\n"); goto bail; } - *(uint32_t *)ha->start = lba2chs(&iter->di, gp->lba_first); - *(uint32_t *)ha->end = lba2chs(&iter->di, gp->lba_last); + *(uint32_t *)ha->start = lba2chs(&iter->di, gp->lba_first, l2c_cadd); + *(uint32_t *)ha->end = lba2chs(&iter->di, gp->lba_last, l2c_cadd); ha->active_flag = 0x80; ha->ostype = 0xED; /* All bits set by default */ @@ -603,8 +603,8 @@ static int setup_handover(const struct part_iter *iter, goto bail; } if (!iter->index) { - *(uint32_t *)ha->start = lba2chs(&iter->di, 0); - *(uint32_t *)ha->end = lba2chs(&iter->di, 2879); + *(uint32_t *)ha->start = lba2chs(&iter->di, 0, l2c_cadd); + *(uint32_t *)ha->end = lba2chs(&iter->di, 2879, l2c_cadd); ha->active_flag = 0x80; ha->ostype = 0xDA; ha->start_lba = 0; @@ -612,8 +612,8 @@ static int setup_handover(const struct part_iter *iter, } else if (iter->type == typedos) { dp = (const struct disk_dos_part_entry *)iter->record; - *(uint32_t *)ha->start = lba2chs(&iter->di, iter->start_lba); - *(uint32_t *)ha->end = lba2chs(&iter->di, iter->start_lba + dp->length - 1); + *(uint32_t *)ha->start = lba2chs(&iter->di, iter->start_lba, l2c_cadd); + *(uint32_t *)ha->end = lba2chs(&iter->di, iter->start_lba + dp->length - 1, l2c_cadd); ha->active_flag = dp->active_flag; ha->ostype = dp->ostype; ha->start_lba = (uint32_t)iter->start_lba; /* fine, we iterate over legacy scheme */ @@ -784,7 +784,11 @@ int main(int argc, char *argv[]) memcpy(data + ndata++, &hdat, sizeof(hdat)); #ifdef DEBUG - printf("iter dsk: %d\n", iter->di.disk); + printf("iter->di dsk, bps: %X, %u\niter->di lbacnt, C*H*S: %llu, %u\n" + "iter->di C, H, S: %u, %u, %u\n", + iter->di.disk, iter->di.bps, + iter->di.lbacnt, iter->di.cyl * iter->di.head * iter->di.spt, + iter->di.cyl, iter->di.head, iter->di.spt); printf("iter idx: %d\n", iter->index); printf("iter lba: %llu\n", iter->start_lba); if (opt.hand) diff --git a/com32/chain/mangle.c b/com32/chain/mangle.c index 277e219..0d8d7f0 100644 --- a/com32/chain/mangle.c +++ b/com32/chain/mangle.c @@ -250,7 +250,7 @@ static int mangle_bpb(const struct part_iter *iter, struct data_area *data) /* BPB: legacy geometry */ if (type >= bpbV30) { if (iter->di.cbios) - *(uint32_t *)((char *)data->data + 0x18) = (uint32_t)((iter->di.head << 16) | iter->di.sect); + *(uint32_t *)((char *)data->data + 0x18) = (uint32_t)((iter->di.head << 16) | iter->di.spt); else { if (iter->di.disk & 0x80) *(uint32_t *)((char *)data->data + 0x18) = 0x00FF003F; @@ -347,7 +347,7 @@ int mangles_save(const struct part_iter *iter, const struct data_area *data, voi return 0; if (memcmp(org, data->data, data->size)) { - if (disk_write_sector(&iter->di, iter->start_lba, data->data)) { + if (disk_write_sectors(&iter->di, iter->start_lba, data->data, 1)) { error("Cannot write the updated sector.\n"); goto bail; } diff --git a/com32/chain/utility.c b/com32/chain/utility.c index 9824952..b30042b 100644 --- a/com32/chain/utility.c +++ b/com32/chain/utility.c @@ -27,7 +27,7 @@ void error(const char *msg) int guid_is0(const struct guid *guid) { - return !*(const uint64_t *)guid && !*((const uint64_t *)guid+1); + return !*(const uint64_t *)guid && !*((const uint64_t *)guid + 1); } void wait_key(void) @@ -48,19 +48,23 @@ void wait_key(void) } while (!cnt || (cnt < 0 && errno == EAGAIN)); } -uint32_t lba2chs(const struct disk_info *di, uint64_t lba) +uint32_t lba2chs(const struct disk_info *di, uint64_t lba, uint32_t mode) { uint32_t c, h, s, t; uint32_t cs, hs, ss; /* - * Not much reason here, but if we have no valid chs geometry, we assume + * Not much reason here, but if we have no valid CHS geometry, we assume * "typical" ones to have something to return. */ if (di->cbios) { cs = di->cyl; hs = di->head; - ss = di->sect; + ss = di->spt; + if (mode == l2c_cadd && cs < 1024 && di->lbacnt > cs*hs*ss) + cs++; + else if (mode == l2c_cmax) + cs = 1024; } else { if (di->disk & 0x80) { cs = 1024; diff --git a/com32/chain/utility.h b/com32/chain/utility.h index 4f50e0e..db55bc7 100644 --- a/com32/chain/utility.h +++ b/com32/chain/utility.h @@ -13,10 +13,14 @@ #define bpbVNT 6 #define bpbV70 7 +#define l2c_cnul 0 +#define l2c_cadd 1 +#define l2c_cmax 2 + void error(const char *msg); int guid_is0(const struct guid *guid); void wait_key(void); -uint32_t lba2chs(const struct disk_info *di, uint64_t lba); +uint32_t lba2chs(const struct disk_info *di, uint64_t lba, uint32_t mode); uint32_t get_file_lba(const char *filename); int drvoff_detect(int type, unsigned int *off); int bpb_detect(const uint8_t *bpb); -- 2.7.4