From c52f543cf8deab986e0435262ee660a8e300b04f Mon Sep 17 00:00:00 2001
From: Khitiara <robotbrainify@gmail.com>
Date: Fri, 30 May 2025 22:09:17 -0400
Subject: [PATCH] slowly getting started

---
 .gitignore                                |   3 +-
 src/components/part/GptPartitionTable.zig | 147 +++++++++++++++-------
 2 files changed, 106 insertions(+), 44 deletions(-)

diff --git a/.gitignore b/.gitignore
index dfe5b37..a5652ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 .zig-cache/
 zig-out/
 .vscode/
-.dim-out/
\ No newline at end of file
+.dim-out/
+.idea/
\ No newline at end of file
diff --git a/src/components/part/GptPartitionTable.zig b/src/components/part/GptPartitionTable.zig
index 0252037..2cb9c97 100644
--- a/src/components/part/GptPartitionTable.zig
+++ b/src/components/part/GptPartitionTable.zig
@@ -6,63 +6,124 @@ pub fn execute(ctx: dim.Context) !void {
     @panic("gpt-part not implemented yet!");
 }
 
-pub const gpt = struct {
-    pub const Guid = [16]u8;
+const block_size = 512;
 
-    pub const Table = struct {
-        disk_id: Guid,
+const PartTable = @This();
 
-        partitions: []const Partition,
-    };
+disk_id: Guid,
+partitions: []Partition,
 
-    pub const Partition = struct {
-        type: Guid,
-        part_id: Guid,
+fn render(table: *PartTable, stream: *dim.BinaryStream) dim.Content.RenderError!void {
+    {
+        var pmbr: [block_size]u8 = @splat(0);
+        var efi_prot: *[16]u8 = &pmbr[0x1BE..][0..16];
+        std.mem.writeInt(u48, &efi_prot[1], 0x000200, .little);
+        efi_prot[4] = 0xEE;
+        // TODO: ending CHS
+        std.mem.writeInt(u64, &efi_prot[8], 1, .little);
+        // TODO: size in LBA
 
-        offset: ?u64 = null,
-        size: u64,
+        pmbr[0x01FE] = 0x55;
+        pmbr[0x01FF] = 0xAA;
 
-        name: [36]u16,
+        try stream.write(0, &pmbr);
+    }
+    {
+        var gpt_header: [block_size]u8 = @splat(0);
+        @memcpy(&gpt_header[0..8], "EFI PART");
+        std.mem.writeInt(u32, &gpt_header[8..12], 0x00010000, .little);
+        std.mem.writeInt(u32, &gpt_header[12..16], 96, .little);
+        // TODO: header CRC
+        std.mem.writeInt(u64, &gpt_header[24..32], 1, .little);
+        // TODO: alternate lba
+        // TODO: first usable lba
+        // TODO: last usable lba
+        @memcpy(&gpt_header[56..72], &table.disk_id);
+        std.mem.writeInt(u64, &gpt_header[72..80], 2, .little);
+        std.mem.writeInt(u32, &gpt_header[80..84], table.partitions.len, .little);
+        std.mem.writeInt(u32, &gpt_header[84..88], 128, .little);
+        // TODO: partition array CRC
+    }
+}
 
-        attributes: Attributes,
+pub const Guid = [16]u8;
 
-        // data: Content,
+fn parseGuid(str: []const u8) !Guid {
+    @setEvalBranchQuota(4096);
 
-        pub const Attributes = packed struct(u32) {
-            system: bool,
-            efi_hidden: bool,
-            legacy: bool,
-            read_only: bool,
-            hidden: bool,
-            no_automount: bool,
+    var guid: Guid = undefined;
 
-            padding: u26 = 0,
-        };
-    };
+    if (str.len != 36 or std.mem.count(u8, str, "-") != 4 or str[8] != '-' or str[13] != '-' or str[18] != '-' or str[23] != '-') {
+        return error.InvalidUuid;
+    }
+
+    const set_1 = try std.fmt.parseInt(u32, str[0..8], 16);
+    const set_2 = try std.fmt.parseInt(u16, str[9..13], 16);
+    const set_3 = try std.fmt.parseInt(u16, str[14..18], 16);
+    const set_4 = try std.fmt.parseInt(u16, str[19..23], 16);
+    const set_5 = try std.fmt.parseInt(u48, str[24..36], 16);
+
+    std.mem.writeInt(u32, &guid[0], set_1, .big);
+    std.mem.writeInt(u16, &guid[4], set_2, .big);
+    std.mem.writeInt(u16, &guid[6], set_3, .big);
+    std.mem.writeInt(u16, &guid[8], set_4, .big);
+    std.mem.writeInt(u48, &guid[10], set_5, .big);
+
+    return guid;
+}
+
+pub const Partition = struct {
+    type: Guid,
+    part_id: Guid,
 
-    /// https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs
-    pub const PartitionType = struct {
-        pub const unused: Guid = .{};
+    offset: ?u64 = null,
+    size: u64,
 
-        pub const microsoft_basic_data: Guid = .{};
-        pub const microsoft_reserved: Guid = .{};
+    name: [35:0]u16,
 
-        pub const windows_recovery: Guid = .{};
+    attributes: Attributes,
 
-        pub const plan9: Guid = .{};
+    data: dim.Content,
 
-        pub const linux_swap: Guid = .{};
-        pub const linux_fs: Guid = .{};
-        pub const linux_reserved: Guid = .{};
-        pub const linux_lvm: Guid = .{};
+    pub const Attributes = packed struct(u32) {
+        system: bool,
+        efi_hidden: bool,
+        legacy: bool,
+        read_only: bool,
+        hidden: bool,
+        no_automount: bool,
+
+        padding: u10 = 0,
+        user: u16,
     };
+};
 
-    pub fn nameLiteral(comptime name: []const u8) [36]u16 {
-        return comptime blk: {
-            var buf: [36]u16 = undefined;
-            const len = std.unicode.utf8ToUtf16Le(&buf, name) catch |err| @compileError(@tagName(err));
-            @memset(buf[len..], 0);
-            break :blk &buf;
-        };
-    }
+/// https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs
+pub const PartitionType = struct {
+    pub const unused: Guid = parseGuid("00000000-0000-0000-0000-000000000000") catch unreachable;
+
+    pub const esp: Guid = parseGuid("C12A7328-F81F-11D2-BA4B-00A0C93EC93B") catch unreachable;
+    pub const legacy_mbr: Guid = parseGuid("024DEE41-33E7-11D3-9D69-0008C781F39F") catch unreachable;
+    pub const bios_boot: Guid = parseGuid("21686148-6449-6E6F-744E-656564454649") catch unreachable;
+
+    pub const microsoft_basic_data: Guid = parseGuid("EBD0A0A2-B9E5-4433-87C0-68B6B72699C7") catch unreachable;
+    pub const microsoft_reserved: Guid = parseGuid("E3C9E316-0B5C-4DB8-817D-F92DF00215AE") catch unreachable;
+
+    pub const windows_recovery: Guid = parseGuid("DE94BBA4-06D1-4D40-A16A-BFD50179D6AC") catch unreachable;
+
+    pub const plan9: Guid = parseGuid("C91818F9-8025-47AF-89D2-F030D7000C2C") catch unreachable;
+
+    pub const linux_swap: Guid = parseGuid("0657FD6D-A4AB-43C4-84E5-0933C84B4F4F") catch unreachable;
+    pub const linux_fs: Guid = parseGuid("0FC63DAF-8483-4772-8E79-3D69D8477DE4") catch unreachable;
+    pub const linux_reserved: Guid = parseGuid("8DA63339-0007-60C0-C436-083AC8230908") catch unreachable;
+    pub const linux_lvm: Guid = parseGuid("E6D6D379-F507-44C2-A23C-238F2A3DF928") catch unreachable;
 };
+
+pub fn nameLiteral(comptime name: []const u8) [35:0]u16 {
+    return comptime blk: {
+        var buf: [35:0]u16 = undefined;
+        const len = std.unicode.utf8ToUtf16Le(&buf, name) catch |err| @compileError(@tagName(err));
+        @memset(buf[len..], 0);
+        break :blk &buf;
+    };
+}