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

Michal Soltys soltys at ziu.info
Mon Nov 5 16:32:51 PST 2012


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 c7e09eb..bcd31e0 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) = (uint32_t)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) = (uint16_t)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) = (uint32_t)((iter->di.head << 16) | iter->di.spt);
 	else {
@@ -378,6 +381,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 9ec829a..abf642c 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)
@@ -172,6 +173,8 @@ int drvoff_detect(int type)
 	return 0x24;
     } else if (type == bpbV70) {
 	return 0x40;
+    } else if (type == bpbEXF) {
+	return 0x6F;
     }
 
     return -1;
@@ -184,6 +187,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 24959d3..a5b06cc 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 */
 #define l2c_cnul 0
-- 
1.7.10.4




More information about the Syslinux mailing list