aboutsummaryrefslogtreecommitdiffstats
path: root/com32/chain/utility.c
diff options
context:
space:
mode:
authorMichal Soltys <soltys@ziu.info>2010-08-28 01:06:13 +0200
committerMichal Soltys <soltys@ziu.info>2010-09-28 09:32:52 +0200
commit0d591b9348e43cf59cd4857dcc0e9029566d96e5 (patch)
tree5916f3f441a6cca1434c3f44ffe12f55feba774e /com32/chain/utility.c
parent32bcebfdcf56da6b27688d2b78dc42ef59453dd0 (diff)
downloadsyslinux-0d591b9348e43cf59cd4857dcc0e9029566d96e5.tar.gz
syslinux-0d591b9348e43cf59cd4857dcc0e9029566d96e5.tar.xz
syslinux-0d591b9348e43cf59cd4857dcc0e9029566d96e5.zip
chain module: setbpb changes, bss & bs options, bugfixes
Generic function detecting BPB type (7 versions) have been added. set{hid,geo,drv} have been replaced by single setbpb option, using mentioned function to make more precise decisions what to update where. Full BSS and BS emulation has been added, also employing BPB detection. Some logic/flow changes in chain's main(). There was also a bug, in which backup sector was populated with wrong data. Appropriate documentation updates. Signed-off-by: Michal Soltys <soltys@ziu.info>
Diffstat (limited to 'com32/chain/utility.c')
-rw-r--r--com32/chain/utility.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/com32/chain/utility.c b/com32/chain/utility.c
index 5aa196df..6894305f 100644
--- a/com32/chain/utility.c
+++ b/com32/chain/utility.c
@@ -112,4 +112,72 @@ uint32_t get_file_lba(const char *filename)
return lba;
}
+/* drive offset detection */
+int drvoff_detect(int type, unsigned int *off)
+{
+ if (bpbV40 <= type && type <= bpbVNT) {
+ *off = 0x24;
+ } else if (type == bpbV70) {
+ *off = 0x40;
+ } else
+ return 0;
+
+ return -1;
+}
+
+/*
+ * heuristics could certainly be improved
+ */
+int bpb_detect(const uint8_t *sec)
+{
+ int a, b, c, jmp = -1, rev = -1;
+
+ /* media descriptor check */
+ if ((sec[0x15] & 0xF0) != 0xF0)
+ return -1;
+
+ if (sec[0] == 0xEB) /* jump short */
+ jmp = 2 + *(int8_t *)(sec + 1);
+ else if (sec[0] == 0xE9) /* jump near */
+ jmp = 3 + *(int16_t *)(sec + 1);
+
+ if (jmp < 0) /* no boot code at all ? */
+ goto nocode;
+
+ /* sanity */
+ if (jmp < 0x18 || jmp > 0x1F0)
+ return -1;
+
+ /* detect by jump */
+ if (jmp >= 0x18 && jmp < 0x1E)
+ rev = bpbV20;
+ else if (jmp >= 0x1E && jmp < 0x20)
+ rev = bpbV30;
+ else if (jmp >= 0x20 && jmp < 0x24)
+ rev = bpbV32;
+ else if (jmp >= 0x24 && jmp < 0x46)
+ rev = bpbV34;
+
+ /* TODO: some better V2 - V3.4 checks ? */
+
+ if (rev >= 0)
+ return rev;
+
+nocode:
+ a = memcmp(sec + 0x03, "NTFS", 4);
+ b = memcmp(sec + 0x36, "FAT", 3);
+ c = memcmp(sec + 0x52, "FAT", 3); /* ext. DOS 7+ bs */
+
+ if ((sec[0x26] & 0xFE) == 0x28 && !b) {
+ rev = bpbV40;
+ } else if (sec[0x26] == 0x80 && !a) {
+ rev = bpbVNT;
+ } else if ((sec[0x42] & 0xFE) == 0x28 && !c) {
+ rev = bpbV70;
+ }
+
+ return rev;
+}
+
+
/* vim: set ts=8 sts=4 sw=4 noet: */