[syslinux] [PATCH 17/28] com32/chain: recognize exFAT

Michal Soltys soltys at ziu.info
Tue Jan 29 06:06:04 PST 2013


The usual stuff - hidden sectors (now 64bit at different offset),
drive offest, "BPB" type.

Formally (?) region from 0x0B to 0x3F should be 0, but ... it's
tempting to fill "old" values there. Might be worth adding a switch to
handle such behavior.

Signed-off-by: Michal Soltys <soltys at ziu.info>
---
 com32/chain/mangle.c  |   13 +++++++++----
 com32/chain/utility.c |    9 +++++++++
 com32/chain/utility.h |    1 +
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/com32/chain/mangle.c b/com32/chain/mangle.c
index 94e6e90..e1f7ae3 100644
--- a/com32/chain/mangle.c
+++ b/com32/chain/mangle.c
@@ -279,24 +279,27 @@ static int mangle_bpb(const struct part_iter *iter, struct data_area *data, cons
     int type = bpb_detect(data->data, tag);
     int off = drvoff_detect(type);
 
+    /* BPB: hidden sectors 64bit - exFAT only for now */
+    if (type == bpbEXF)
+	    *(uint64_t *) ((char *)data->data + 0x40) = iter->start_lba;
     /* BPB: hidden sectors 32bit*/
-    if (type >= bpbV34) {
+    else if (bpbV34 <= type && type <= bpbV70) {
 	if (iter->start_lba < ~0u)
 	    *(uint32_t *) ((char *)data->data + 0x1c) = iter->start_lba;
 	else
 	    /* won't really help much, but ... */
 	    *(uint32_t *) ((char *)data->data + 0x1c) = ~0u;
-    }
     /* BPB: hidden sectors 16bit*/
-    if (bpbV30 <= type && type <= bpbV32) {
+    } else if (bpbV30 <= type && type <= bpbV32) {
 	if (iter->start_lba < 0xFFFF)
 	    *(uint16_t *) ((char *)data->data + 0x1c) = iter->start_lba;
 	else
 	    /* won't really help much, but ... */
 	    *(uint16_t *) ((char *)data->data + 0x1c) = (uint16_t)~0u;
     }
+
     /* BPB: legacy geometry */
-    if (type >= bpbV30) {
+    if (bpbV30 <= type && type <= bpbV70) {
 	if (iter->di.cbios)
 	    *(uint32_t *)((char *)data->data + 0x18) = (iter->di.head << 16) | iter->di.spt;
 	else {
@@ -377,6 +380,8 @@ int manglesf_bss(struct data_area *sec, struct data_area *fil)
 	cnt = 0x3C;
     } else if (type1 <= bpbV70) {
 	cnt = 0x42;
+    } else if (type1 <= bpbEXF) {
+	cnt = 0x60;
     }
     memcpy((char *)fil->data + 0x18, (char *)sec->data + 0x18, cnt);
 
diff --git a/com32/chain/utility.c b/com32/chain/utility.c
index 30eec6d..1e2dfdd 100644
--- a/com32/chain/utility.c
+++ b/com32/chain/utility.c
@@ -46,6 +46,7 @@ static const char *bpbtypes[] = {
     [5] =  "4.0",
     [6] =  "8.0 (NT+)",
     [7] =  "7.0",
+    [8] =  "exFAT",
 };
 
 void wait_key(void)
@@ -182,6 +183,8 @@ int drvoff_detect(int type)
 	return 0x24;
     } else if (type == bpbV70) {
 	return 0x40;
+    } else if (type == bpbEXF) {
+	return 0x6F;
     }
 
     return -1;
@@ -194,6 +197,12 @@ int bpb_detect(const uint8_t *sec, const char *tag)
 {
     int a, b, c, jmp = -1, rev = 0;
 
+    /* exFAT mess first (media descriptor is 0 here) */
+    if (!memcmp(sec + 0x03, "EXFAT   ", 8)) {
+	rev = bpbEXF;
+	goto out;
+    }
+
     /* media descriptor check */
     if ((sec[0x15] & 0xF0) != 0xF0)
 	goto out;
diff --git a/com32/chain/utility.h b/com32/chain/utility.h
index ac056dc..08442ae 100644
--- a/com32/chain/utility.h
+++ b/com32/chain/utility.h
@@ -43,6 +43,7 @@
 #define bpbV40	5
 #define bpbVNT	6
 #define bpbV70	7
+#define bpbEXF	8
 
 /* see utility.c for details */
 enum {L2C_CNUL, L2C_CADD, L2C_CMAX};
-- 
1.7.10.4



More information about the Syslinux mailing list