Skip to content

Commit c051270

Browse files
author
Felix "xq" Queißner
committed
More work on the MBR part table
1 parent 86a3ba5 commit c051270

File tree

6 files changed

+70
-8
lines changed

6 files changed

+70
-8
lines changed

justfile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ behaviour-tests: \
1717
(behaviour-test "tests/basic/fill-0xAA.dis") \
1818
(behaviour-test "tests/basic/fill-0xFF.dis") \
1919
(behaviour-test "tests/basic/raw.dis") \
20-
(behaviour-test "tests/part/mbr/minimal.dis")
20+
(behaviour-test "tests/part/mbr/minimal.dis") \
21+
(behaviour-test "tests/part/mbr/no-part-bootloader.dis") \
22+
(behaviour-test "tests/part/mbr/basic-single-part-sized.dis") \
23+
(behaviour-test "tests/part/mbr/basic-single-part-unsized.dis")
2124

2225
behaviour-test script: install
2326
./zig-out/bin/dim --output .zig-cache/disk.img --script "{{script}}"

src/components/part/MbrPartitionTable.zig

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub fn parse(ctx: dim.Context) !dim.Content {
2525
};
2626

2727
var next_part_id: usize = 0;
28+
var last_part_id: ?usize = null;
2829
while (next_part_id < pf.partitions.len) {
2930
const kw = try ctx.parse_enum(enum {
3031
bootloader,
@@ -45,11 +46,20 @@ pub fn parse(ctx: dim.Context) !dim.Content {
4546
},
4647
.part => {
4748
pf.partitions[next_part_id] = try parse_partition(ctx);
49+
last_part_id = next_part_id;
4850
next_part_id += 1;
4951
},
5052
}
5153
}
5254

55+
if (last_part_id) |part_id| {
56+
for (0..part_id -| 1) |prev| {
57+
if (pf.partitions[prev].?.size == null) {
58+
try ctx.report_nonfatal_error("MBR partition {} does not have a size, but is not last.", .{prev});
59+
}
60+
}
61+
}
62+
5363
return .create_handle(pf, .create(PartTable, .{
5464
.guess_size_fn = guess_size,
5565
.render_fn = render,
@@ -62,7 +72,7 @@ fn parse_partition(ctx: dim.Context) !Partition {
6272
.size = null,
6373
.bootable = false,
6474
.type = .empty,
65-
.data = .empty,
75+
.contains = .empty,
6676
};
6777

6878
var updater: dim.FieldUpdater(Partition, &.{
@@ -77,15 +87,15 @@ fn parse_partition(ctx: dim.Context) !Partition {
7787
bootable,
7888
size,
7989
offset,
80-
contents,
90+
contains,
8191
endpart,
8292
});
8393
try switch (kw) {
8494
.type => updater.set(.type, try ctx.parse_enum(PartitionType)),
8595
.bootable => updater.set(.bootable, true),
8696
.size => updater.set(.size, try ctx.parse_mem_size()),
8797
.offset => updater.set(.offset, try ctx.parse_mem_size()),
88-
.contents => updater.set(.data, try ctx.parse_content()),
98+
.contains => updater.set(.contains, try ctx.parse_content()),
8999
.endpart => break :parse_loop,
90100
};
91101
}
@@ -96,7 +106,31 @@ fn parse_partition(ctx: dim.Context) !Partition {
96106
}
97107

98108
fn guess_size(self: *PartTable) dim.Content.GuessError!dim.SizeGuess {
99-
_ = self;
109+
var upper_bound: u64 = 512;
110+
var all_parts_bounded = true;
111+
112+
for (self.partitions) |mpart| {
113+
const part = mpart orelse continue;
114+
115+
if (part.offset != null and part.size != null) {
116+
upper_bound = @max(upper_bound, part.offset.? + part.size.?);
117+
} else {
118+
all_parts_bounded = false;
119+
}
120+
}
121+
if (all_parts_bounded)
122+
return .{ .exact = upper_bound };
123+
124+
for (self.partitions) |mpart| {
125+
const part = mpart orelse continue;
126+
127+
if (part.offset != null and part.size != null) {
128+
upper_bound = @max(upper_bound, part.offset.? + part.size.?);
129+
} else {
130+
all_parts_bounded = false;
131+
}
132+
}
133+
100134
@panic("not implemented yet!");
101135
}
102136

@@ -211,7 +245,7 @@ pub const Partition = struct {
211245
.size = 0,
212246
.bootable = false,
213247
.type = .empty,
214-
.data = undefined,
248+
.contains = .empty,
215249
};
216250

217251
offset: ?u64 = null,
@@ -220,7 +254,7 @@ pub const Partition = struct {
220254
bootable: bool,
221255
type: PartitionType,
222256

223-
data: dim.Content,
257+
contains: dim.Content,
224258
};
225259

226260
/// https://en.wikipedia.org/wiki/Partition_type

src/dim.zig

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ pub fn main() !u8 {
122122
return 1;
123123
}
124124

125+
const root_size_estimation = try root_content.guess_required_size();
126+
std.log.info("root size: {}", .{root_size_estimation});
127+
125128
{
126129
var output_file = try current_dir.atomicFile(output_path, .{});
127130
defer output_file.deinit();
@@ -542,7 +545,6 @@ pub const SizeGuess = union(enum) {
542545
unknown,
543546
exact: u64,
544547
at_least: u64,
545-
at_most: u64,
546548
};
547549

548550
pub const BinaryStream = struct {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
mbr-part
2+
part
3+
type empty
4+
contains fill 0xAA
5+
size 10M
6+
endpart
7+
ignore # partition 2
8+
ignore # partition 3
9+
ignore # partition 4
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
mbr-part
2+
part
3+
type empty
4+
contains fill 0xAA
5+
endpart
6+
ignore # partition 2
7+
ignore # partition 3
8+
ignore # partition 4

tests/part/mbr/no-part-bootloader.dis

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
mbr-part
2+
bootloader paste-file ./minimal.dis
3+
ignore # partition 1
4+
ignore # partition 2
5+
ignore # partition 3
6+
ignore # partition 4

0 commit comments

Comments
 (0)