Skip to content

[WIP] GPT Support #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.zig-cache/
zig-out/
.vscode/
.dim-out/
.dim-out/
.idea/
147 changes: 104 additions & 43 deletions src/components/part/GptPartitionTable.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
}