aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Soltys <soltys@ziu.info>2010-09-28 19:57:28 +0200
committerMichal Soltys <soltys@ziu.info>2010-10-08 12:40:51 +0200
commit81f86009696b5c7eff76e1981e967367235c5f7c (patch)
tree9f7d86b09f75877da049c9fab6321b8547255cd0
parent71485af3c0b47409fbd721d83f20fb8fcac76e42 (diff)
downloadsyslinux-81f86009696b5c7eff76e1981e967367235c5f7c.tar.gz
syslinux-81f86009696b5c7eff76e1981e967367235c5f7c.tar.xz
syslinux-81f86009696b5c7eff76e1981e967367235c5f7c.zip
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 <soltys@ziu.info>
-rw-r--r--com32/chain/Makefile4
-rw-r--r--com32/chain/chain.c26
-rw-r--r--com32/chain/mangle.c4
-rw-r--r--com32/chain/utility.c12
-rw-r--r--com32/chain/utility.h6
5 files changed, 31 insertions, 21 deletions
diff --git a/com32/chain/Makefile b/com32/chain/Makefile
index 36710ffb..a5602d9d 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 de9e0ec6..d33da6af 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 277e219d..0d8d7f02 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 98249529..b30042b5 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 4f50e0ea..db55bc7d 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);