forked from WerWolv/ImHex-Patterns
-
Notifications
You must be signed in to change notification settings - Fork 0
/
uf2.hexpat
101 lines (83 loc) · 2.29 KB
/
uf2.hexpat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#pragma author WerWolv
#pragma description [USB Flashing Format](https://github.com/microsoft/uf2)
#include <std/sys.pat>
#include <std/mem.pat>
#pragma MIME application/microformats+json
#pragma MIME application/microformats2+json
#pragma MIME application/mf2+json
#pragma MIME application/uf2+json
#pragma pattern_limit 100000
bitfield UF2_Flags {
NotMainFlash : 1;
padding : 11;
FileContainer : 1;
FamilyIDPresent : 1;
MD5ChecksumPresent : 1;
ExtensionTagsPresent : 1;
padding : 16;
};
struct UF2_Hash {
u32 startAddress;
u32 size;
u8 md5Checksum[16];
} [[static]];
struct UF2_TagType {
u8 bytes[3];
} [[format("formatTagType")]];
enum UF2_TagTypeEnum : u32 {
FirmwareFileVersion = 0x9FC7BC,
DeviceDescription = 0x650D9D,
TargetPageSize = 0x0BE9F7,
SHA1Checksum = 0xB46DB0,
DeviceTypeIdentifier = 0xC8A729
};
fn formatTagType(UF2_TagType type) {
u32 value = (type.bytes[0] << 16) | (type.bytes[1] << 8) | (type.bytes[2]);
if (value == UF2_TagTypeEnum::FirmwareFileVersion)
return "Firmware File Version";
else if (value == UF2_TagTypeEnum::DeviceDescription)
return "Device Description";
else if (value == UF2_TagTypeEnum::TargetPageSize)
return "Target Page Size";
else if (value == UF2_TagTypeEnum::SHA1Checksum)
return "SHA1 Checksum";
else if (value == UF2_TagTypeEnum::DeviceTypeIdentifier)
return "Device Type Identifier";
else
return "Custom Type";
};
struct UF2_ExtensionTag {
u8 size;
UF2_TagType type;
u8 data[size - 4];
if (size == 0 && type.bytes[0] == 0x00 && type.bytes[1] == 0x00 && type.bytes[2] == 0x00)
break;
};
struct UF2_Block {
char magicStart0[4];
u32 magicStart1;
UF2_Flags flags;
u32 targetAddr;
u32 payloadSize;
u32 blockNo;
u32 numBlocks;
if (flags.FamilyIDPresent)
u32 familyId;
else
u32 fileSize;
if (flags.MD5ChecksumPresent) {
u8 data[452];
UF2_Hash hash;
}
else {
u8 data[476];
}
if (flags.ExtensionTagsPresent) {
UF2_ExtensionTag extensionTags[0xFF];
}
u32 magicEnd;
std::assert(magicStart0 == "UF2\n", "Invalid magicStart0 value!");
std::assert(magicStart1 == 0x9E5D5157, "Invalid magicStart1 value!");
std::assert(magicEnd == 0x0AB16F30, "Invalid magicEnd value!");
};
UF2_Block block[while(!std::mem::eof())] @ 0;