Skip to content

Commit 5e967ce

Browse files
committed
Add brand new Partition Offsets Helper Tool
1 parent 07523ce commit 5e967ce

File tree

7 files changed

+516
-6
lines changed

7 files changed

+516
-6
lines changed

FirmwareGen.sln

+24-6
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,52 @@ VisualStudioVersion = 17.9.34407.89
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FirmwareGen", "FirmwareGen\FirmwareGen.csproj", "{85918ACF-6909-45DA-B56D-3D5113B7EA6C}"
77
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PartitionOffsetsHelperTool", "PartitionOffsetsHelperTool\PartitionOffsetsHelperTool.csproj", "{AC699AC2-883A-4278-B2A8-F0F693DC8643}"
9+
EndProject
810
Global
911
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1012
Debug|Any CPU = Debug|Any CPU
13+
Debug|ARM64 = Debug|ARM64
1114
Debug|x64 = Debug|x64
1215
Debug|x86 = Debug|x86
13-
Debug|ARM64 = Debug|ARM64
1416
Release|Any CPU = Release|Any CPU
17+
Release|ARM64 = Release|ARM64
1518
Release|x64 = Release|x64
1619
Release|x86 = Release|x86
17-
Release|ARM64 = Release|ARM64
1820
EndGlobalSection
1921
GlobalSection(ProjectConfigurationPlatforms) = postSolution
2022
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2123
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
24+
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Debug|ARM64.ActiveCfg = Debug|ARM64
25+
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Debug|ARM64.Build.0 = Debug|ARM64
2226
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Debug|x64.ActiveCfg = Debug|Any CPU
2327
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Debug|x64.Build.0 = Debug|Any CPU
2428
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Debug|x86.ActiveCfg = Debug|x86
2529
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Debug|x86.Build.0 = Debug|x86
26-
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Debug|ARM64.ActiveCfg = Debug|ARM64
27-
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Debug|ARM64.Build.0 = Debug|ARM64
2830
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
2931
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Release|Any CPU.Build.0 = Release|Any CPU
32+
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Release|ARM64.ActiveCfg = Release|ARM64
33+
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Release|ARM64.Build.0 = Release|ARM64
3034
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Release|x64.ActiveCfg = Release|x64
3135
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Release|x64.Build.0 = Release|x64
3236
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Release|x86.ActiveCfg = Release|x86
3337
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Release|x86.Build.0 = Release|x86
34-
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Release|ARM64.ActiveCfg = Release|ARM64
35-
{85918ACF-6909-45DA-B56D-3D5113B7EA6C}.Release|ARM64.Build.0 = Release|ARM64
38+
{AC699AC2-883A-4278-B2A8-F0F693DC8643}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39+
{AC699AC2-883A-4278-B2A8-F0F693DC8643}.Debug|Any CPU.Build.0 = Debug|Any CPU
40+
{AC699AC2-883A-4278-B2A8-F0F693DC8643}.Debug|ARM64.ActiveCfg = Debug|Any CPU
41+
{AC699AC2-883A-4278-B2A8-F0F693DC8643}.Debug|ARM64.Build.0 = Debug|Any CPU
42+
{AC699AC2-883A-4278-B2A8-F0F693DC8643}.Debug|x64.ActiveCfg = Debug|Any CPU
43+
{AC699AC2-883A-4278-B2A8-F0F693DC8643}.Debug|x64.Build.0 = Debug|Any CPU
44+
{AC699AC2-883A-4278-B2A8-F0F693DC8643}.Debug|x86.ActiveCfg = Debug|Any CPU
45+
{AC699AC2-883A-4278-B2A8-F0F693DC8643}.Debug|x86.Build.0 = Debug|Any CPU
46+
{AC699AC2-883A-4278-B2A8-F0F693DC8643}.Release|Any CPU.ActiveCfg = Release|Any CPU
47+
{AC699AC2-883A-4278-B2A8-F0F693DC8643}.Release|Any CPU.Build.0 = Release|Any CPU
48+
{AC699AC2-883A-4278-B2A8-F0F693DC8643}.Release|ARM64.ActiveCfg = Release|Any CPU
49+
{AC699AC2-883A-4278-B2A8-F0F693DC8643}.Release|ARM64.Build.0 = Release|Any CPU
50+
{AC699AC2-883A-4278-B2A8-F0F693DC8643}.Release|x64.ActiveCfg = Release|Any CPU
51+
{AC699AC2-883A-4278-B2A8-F0F693DC8643}.Release|x64.Build.0 = Release|Any CPU
52+
{AC699AC2-883A-4278-B2A8-F0F693DC8643}.Release|x86.ActiveCfg = Release|Any CPU
53+
{AC699AC2-883A-4278-B2A8-F0F693DC8643}.Release|x86.Build.0 = Release|Any CPU
3654
EndGlobalSection
3755
GlobalSection(SolutionProperties) = preSolution
3856
HideSolutionNode = FALSE
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using PartitionOffsetsHelperTool.GPT;
2+
3+
namespace PartitionOffsetsHelperTool.DeviceProfiles
4+
{
5+
internal static class Constants
6+
{
7+
// OEMEP DV UFS LUN 0 Partition Layout
8+
internal static readonly GPTPartition[] OEMEP_UFS_LUN_0_PARTITIONS =
9+
[
10+
new()
11+
{
12+
TypeGUID = new Guid("2c86e742-745e-4fdd-bfd8-b6a7ac638772"),
13+
UID = new Guid("3e20174c-e289-a56a-39e7-2740b0043d24"),
14+
FirstLBA = 6,
15+
LastLBA = 7,
16+
Attributes = 0,
17+
Name = "ssd"
18+
},
19+
new()
20+
{
21+
TypeGUID = new Guid("6c95e238-e343-4ba8-b489-8681ed22ad0b"),
22+
UID = new Guid("3c077ac9-fe70-fb01-9fda-3e03153145ea"),
23+
FirstLBA = 8,
24+
LastLBA = 8199,
25+
Attributes = 0,
26+
Name = "persist"
27+
},
28+
new()
29+
{
30+
TypeGUID = new Guid("988a98c9-2910-4123-aaec-1cf6b1bc28f9"),
31+
UID = new Guid("b7f39878-935d-ed4b-ead8-48b159a31e04"),
32+
FirstLBA = 8200,
33+
LastLBA = 12295,
34+
Attributes = 0,
35+
Name = "metadata"
36+
},
37+
new()
38+
{
39+
TypeGUID = new Guid("91b72d4d-71e0-4cbf-9b8e-236381cff17a"),
40+
UID = new Guid("04489c96-ae78-c997-efbf-1bc9909cd1ca"),
41+
FirstLBA = 12296,
42+
LastLBA = 12423,
43+
Attributes = 0,
44+
Name = "frp"
45+
},
46+
new()
47+
{
48+
TypeGUID = new Guid("82acc91f-357c-4a68-9c8f-689e1b1a23a1"),
49+
UID = new Guid("b2ebcd63-842b-f5ff-bdf6-f630f7148b1f"),
50+
FirstLBA = 12424,
51+
LastLBA = 12679,
52+
Attributes = 0,
53+
Name = "misc"
54+
},
55+
new()
56+
{
57+
TypeGUID = new Guid("1b81e7e6-f50d-419b-a739-2aeef8da3335"),
58+
UID = new Guid("e24f3f91-ed89-c235-d6b4-afada6edb8b7"),
59+
FirstLBA = 12680,
60+
LastLBA = 12679,
61+
Attributes = 0,
62+
Name = "userdata"
63+
}
64+
];
65+
}
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
namespace PartitionOffsetsHelperTool.GPT
2+
{
3+
public class GPTPartition
4+
{
5+
public Guid TypeGUID
6+
{
7+
get; set;
8+
}
9+
10+
public Guid UID
11+
{
12+
get; set;
13+
}
14+
15+
public ulong FirstLBA
16+
{
17+
get; set;
18+
}
19+
20+
public ulong LastLBA
21+
{
22+
get; set;
23+
}
24+
25+
public ulong Attributes
26+
{
27+
get; set;
28+
}
29+
30+
public string Name
31+
{
32+
get; set;
33+
}
34+
}
35+
}
+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
using System.Drawing;
2+
3+
namespace PartitionOffsetsHelperTool.GPT
4+
{
5+
internal class GPTUtils
6+
{
7+
internal static void MakeGPT(ulong DiskSize, ulong SectorSize, GPTPartition[] DefaultPartitionTable, ulong AndroidDesiredSpace = 4_294_967_296)
8+
{
9+
ulong LastLBA = DiskSize / SectorSize - 1;
10+
11+
ulong PartitionArrayLBACount = 4;
12+
ulong TotalGPTLBACount = 1 /* GPT Header */ + PartitionArrayLBACount /* Partition Table */;
13+
ulong LastUsableLBA = LastLBA - TotalGPTLBACount;
14+
15+
List<GPTPartition> Partitions = new(DefaultPartitionTable);
16+
Partitions[^1].LastLBA = LastUsableLBA;
17+
18+
if (AndroidDesiredSpace < 4_294_967_296)
19+
{
20+
throw new Exception("ERROR");
21+
}
22+
23+
InjectWindowsPartitions(Partitions, SectorSize, 4, AndroidDesiredSpace);
24+
}
25+
26+
private static void InjectWindowsPartitions(List<GPTPartition> Partitions, ulong SectorSize, ulong BlockSize, ulong AndroidDesiredSpace)
27+
{
28+
ulong FirstUsableLBA = Partitions.Last().FirstLBA;
29+
ulong LastUsableLBA = Partitions.Last().LastLBA;
30+
31+
if (LastUsableLBA % BlockSize != 0)
32+
{
33+
LastUsableLBA -= LastUsableLBA % BlockSize;
34+
}
35+
36+
ulong UsableLBACount = LastUsableLBA - FirstUsableLBA + 1;
37+
38+
ulong SixtyFourGigaBytes = 68_719_476_736 / SectorSize;
39+
40+
ulong ESPLBACount = 65525 + 1024 + 1 /* Cluster Size Limit for FAT32 */;
41+
if (ESPLBACount % BlockSize != 0)
42+
{
43+
ESPLBACount += BlockSize - ESPLBACount % BlockSize;
44+
}
45+
46+
/* Strategy to reserve 4GB for Android Only */
47+
ulong FourGigaBytes = AndroidDesiredSpace / SectorSize;
48+
ulong WindowsLBACount = UsableLBACount - ESPLBACount - FourGigaBytes;
49+
50+
if (WindowsLBACount < SixtyFourGigaBytes)
51+
{
52+
WindowsLBACount = SixtyFourGigaBytes;
53+
}
54+
55+
if (WindowsLBACount % BlockSize != 0)
56+
{
57+
WindowsLBACount -= WindowsLBACount % BlockSize;
58+
}
59+
60+
ulong TotalInjectedLBACount = ESPLBACount + WindowsLBACount;
61+
62+
ulong ESPFirstLBA = LastUsableLBA - TotalInjectedLBACount;
63+
ulong ESPLastLBA = ESPFirstLBA + ESPLBACount - 1;
64+
65+
ulong WindowsFirstLBA = ESPLastLBA + 1;
66+
ulong WindowsLastLBA = ESPLastLBA + WindowsLBACount;
67+
68+
if (ESPFirstLBA % BlockSize != 0)
69+
{
70+
ulong Padding = BlockSize - ESPFirstLBA % BlockSize;
71+
throw new Exception("ESPFirstLBA overflew block alignment by: " + Padding);
72+
}
73+
74+
if ((ESPLastLBA + 1) % BlockSize != 0)
75+
{
76+
ulong Padding = BlockSize - (ESPLastLBA + 1) % BlockSize;
77+
throw new Exception("ESPLastLBA + 1 overflew block alignment by: " + Padding);
78+
}
79+
80+
if (WindowsFirstLBA % BlockSize != 0)
81+
{
82+
ulong Padding = BlockSize - WindowsFirstLBA % BlockSize;
83+
throw new Exception("WindowsFirstLBA overflew block alignment by: " + Padding);
84+
}
85+
86+
if ((WindowsLastLBA + 1) % BlockSize != 0)
87+
{
88+
ulong Padding = BlockSize - (WindowsLastLBA + 1) % BlockSize;
89+
throw new Exception("WindowsLastLBA + 1 overflew block alignment by: " + Padding);
90+
}
91+
92+
Partitions.Add(new()
93+
{
94+
TypeGUID = new Guid("c12a7328-f81f-11d2-ba4b-00a0c93ec93b"),
95+
UID = new Guid("dec2832a-5f6c-430a-bd85-42551bce7b91"),
96+
FirstLBA = ESPFirstLBA,
97+
LastLBA = ESPLastLBA,
98+
Attributes = 0,
99+
Name = "esp"
100+
});
101+
102+
Partitions.Add(new()
103+
{
104+
TypeGUID = new Guid("ebd0a0a2-b9e5-4433-87c0-68b6b72699c7"),
105+
UID = new Guid("92dee62d-ed67-4ec3-9daa-c9a4bce2c355"),
106+
FirstLBA = WindowsFirstLBA,
107+
LastLBA = WindowsLastLBA,
108+
Attributes = 0,
109+
Name = "win"
110+
});
111+
112+
Partitions[^3].LastLBA = ESPFirstLBA - 1;
113+
114+
ConsoleColor ogColor = Console.ForegroundColor;
115+
116+
ulong androidSpaceInBytes = (Partitions[^3].LastLBA - Partitions[^3].FirstLBA) * SectorSize;
117+
ulong windowsSpaceInBytes = (Partitions[^1].LastLBA - Partitions[^1].FirstLBA) * SectorSize;
118+
119+
Console.WriteLine("Resulting Allocation after Computation, Compatibility Checks and Corrections:");
120+
Console.WriteLine();
121+
Console.WriteLine("Android: " + Math.Round(androidSpaceInBytes / (double)(1024 * 1024 * 1024), 2) + "GB");
122+
Console.WriteLine("Windows: " + Math.Round(windowsSpaceInBytes / (double)(1024 * 1024 * 1024), 2) + "GB");
123+
Console.WriteLine();
124+
125+
Console.WriteLine("Resulting parted commands:");
126+
Console.WriteLine();
127+
Console.ForegroundColor = ConsoleColor.Green;
128+
Console.WriteLine($"mkpart {Partitions[^3].Name} ext4 {Partitions[^3].FirstLBA}s {Partitions[^3].LastLBA}s");
129+
Console.WriteLine($"mkpart {Partitions[^2].Name} fat32 {Partitions[^2].FirstLBA}s {Partitions[^2].LastLBA}s");
130+
Console.WriteLine($"mkpart {Partitions[^1].Name} ntfs {Partitions[^1].FirstLBA}s {Partitions[^1].LastLBA}s");
131+
Console.ForegroundColor = ogColor;
132+
}
133+
}
134+
}

0 commit comments

Comments
 (0)