-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParseMBR.ino
127 lines (119 loc) · 3.91 KB
/
ParseMBR.ino
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "config.h"
#include "DebugConsole.h"
#include "LUNS.h"
#include "sdhc.h"
TABLE_t pTable[MAXTABLES];
volatile int pTables = 1;
void ParseMBR(int Table) {
uint8_t mbrbuf[512];
int part;
for(int ii=0;ii<512;ii++) mbrbuf[ii]=0xff;
// Read table
/* DRESULT res = */ SDHC_ReadBlocks((UCHAR*) mbrbuf, (DWORD) pTable[Table].Offset, 1);
SDHC_DMAWait();
for(part = 0; part < 4; part++) {
uint8_t *entry = &mbrbuf[446+16*part];
uint32_t pOffset = *(uint32_t*)&entry[8];
uint32_t pSize = *(uint32_t*)&entry[12];
uint8_t pType = entry[4];
uint8_t tLUN;
pTable[Table].Part[part].Size = pSize;
pTable[Table].Part[part].Type = pType;
switch(pType) {
case 0x00: // Empty
pTable[Table].Part[part].Offset = pOffset;
break;
case 0x05: // Extended
if(pTables < MAXTABLES) {
pTable[Table].Part[part].Offset = pTable[Table].Extended + pOffset;
pTable[pTables].Extended = pTable[Table].Extended;
pTable[pTables].Offset = pTable[Table].Extended + pOffset;
pTables++;
}
break;
case 0x0f: // Extended LBA
if(pTables < MAXTABLES) {
pTable[Table].Part[part].Offset = pTable[Table].Extended + pOffset;
pTable[pTables].Extended = pTable[Table].Extended + pOffset;
pTable[pTables].Offset = pTable[Table].Extended + pOffset;
pTables++;
}
break;
case 0xf8: // Disk LUN
// Find first unused disk LUN
for(tLUN = 0; tLUN < MAXLUNS; tLUN++) {
if (!lun[tLUN].Enabled) continue;
if (lun[tLUN].Type != 0) continue;
if (lun[tLUN].Size != 0) continue;
break;
}
if(tLUN < MAXLUNS) {
lun[tLUN].Type = LUN_DISK_GENERIC;
lun[tLUN].Offset = pTable[Table].Offset + pOffset;
lun[tLUN].Size = pSize;
lun[tLUN].Sectors = 16;
lun[tLUN].SectorSize = 512;
lun[tLUN].Heads = 16;
lun[tLUN].Cylinders = pSize / (lun[tLUN].Heads * lun[tLUN].Sectors);
lun[tLUN].Mounted = 1;
luns++;
}
break;
#ifdef SUPPORT_OPTICAL
case 0xf9: // Optical LUN
for(tLUN = 0; tLUN < MAXLUNS; tLUN++) {
if (!lun[tLUN].Enabled) continue;
if (lun[tLUN].Type != 0) continue;
if (lun[tLUN].Size != 0) continue;
break;
}
if(tLUN < MAXLUNS) {
lun[tLUN].Type = LUN_OPTICAL_GENERIC;
lun[tLUN].Offset = pTable[Table].Offset + pOffset;
lun[tLUN].Size = pSize;
lun[tLUN].Sectors = 1;
lun[tLUN].SectorSize = 2048;
lun[tLUN].Heads = 1;
lun[tLUN].Cylinders = (pSize * 512) / (lun[tLUN].Heads * lun[tLUN].Sectors * lun[tLUN].SectorSize);
lun[tLUN].Mounted = 1;
luns++;
}
break;
#endif
#ifdef SUPPORT_ETHERNET_CABLETRON
case 0xfa: // Ethernet Cabletron
for(tLUN = 0; tLUN < MAXLUNS; tLUN++) {
if (!lun[tLUN].Enabled) continue;
if (lun[tLUN].Type != 0) continue;
if (lun[tLUN].Size != 0) continue;
break;
}
if(tLUN < MAXLUNS) {
lun[tLUN].Type = LUN_ETHERNET_CABLETRON;
lun[tLUN].Offset = pTable[Table].Offset + pOffset;
lun[tLUN].Size = pSize;
luns++;
}
break;
#endif
#ifdef SUPPORT_ETHERNET_SCSILINK
case 0xfb: // Ethernet SCSILink
for(tLUN = 0; tLUN < MAXLUNS; tLUN++) {
if (!lun[tLUN].Enabled) continue;
if (lun[tLUN].Type != 0) continue;
if (lun[tLUN].Size != 0) continue;
break;
}
if(tLUN < MAXLUNS) {
lun[tLUN].Type = LUN_ETHERNET_SCSILINK;
lun[tLUN].Offset = pTable[Table].Offset + pOffset;
lun[tLUN].Size = pSize;
luns++;
}
break;
#endif
}
if(pType)
pTable[Table].Part[part].Offset = pTable[Table].Offset + pOffset;
}
}