aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Soltys <soltys@ziu.info>2013-02-14 16:51:46 +0100
committerMichal Soltys <soltys@ziu.info>2013-02-14 16:53:05 +0100
commit2a6351535426d966745a82be71baf937994cb417 (patch)
treea3cd9412da3478119404d53fe0472c45bcf73041
parentd4ce5b911628423adeb53db8a3cb796f8de2016d (diff)
downloadsyslinux-2a6351535426d966745a82be71baf937994cb417.tar.gz
syslinux-2a6351535426d966745a82be71baf937994cb417.tar.xz
syslinux-2a6351535426d966745a82be71baf937994cb417.zip
com32/chain: recognize exFAT
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@ziu.info>
-rw-r--r--com32/chain/mangle.c13
-rw-r--r--com32/chain/utility.c9
-rw-r--r--com32/chain/utility.h1
3 files changed, 19 insertions, 4 deletions
diff --git a/com32/chain/mangle.c b/com32/chain/mangle.c
index 94e6e90f..e1f7ae33 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 d0da9f8f..7a0ce61c 100644
--- a/com32/chain/utility.c
+++ b/com32/chain/utility.c
@@ -48,6 +48,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 ac056dce..08442aef 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};