com32/chain: utility's lba2chs update
authorMichal Soltys <soltys@ziu.info>
Tue, 28 Sep 2010 17:57:28 +0000 (19:57 +0200)
committerMichal Soltys <soltys@ziu.info>
Fri, 8 Oct 2010 10:40:51 +0000 (12:40 +0200)
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 <soltys@ziu.info>
com32/chain/Makefile
com32/chain/chain.c
com32/chain/mangle.c
com32/chain/utility.c
com32/chain/utility.h

index 36710ff..a5602d9 100644 (file)
@@ -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
index de9e0ec..d33da6a 100644 (file)
@@ -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)
index 277e219..0d8d7f0 100644 (file)
@@ -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;
        }
index 9824952..b30042b 100644 (file)
@@ -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;
index 4f50e0e..db55bc7 100644 (file)
 #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);