summaryrefslogtreecommitdiff
path: root/cmd/convert/convert.ha
diff options
context:
space:
mode:
authorAlejandro Sior <aho@sior.be>2022-06-21 15:38:48 +0200
committerAlejandro Sior <aho@sior.be>2022-06-21 15:38:48 +0200
commitf42a480cbe487fc5fb9b3772990e80926201f6e4 (patch)
treed6af05ea6942732fafa721c97895b66cd42298b3 /cmd/convert/convert.ha
parentd000a6edf4ad9fcc2302a80080fdbebb23fb7378 (diff)
gptman: reorganize commands in a cmd module
Diffstat (limited to 'cmd/convert/convert.ha')
-rw-r--r--cmd/convert/convert.ha58
1 files changed, 58 insertions, 0 deletions
diff --git a/cmd/convert/convert.ha b/cmd/convert/convert.ha
new file mode 100644
index 0000000..807ae7f
--- /dev/null
+++ b/cmd/convert/convert.ha
@@ -0,0 +1,58 @@
+use fmt;
+
+use cmd;
+use mbr;
+use gpt;
+use sector;
+
+use os;
+use io;
+use fs;
+use strings;
+use errors;
+use rt;
+
+export fn convert(vol: str, args: []str) void = {
+ if (len(args) < 2) {
+ fmt::fatalf("convert: needs disk");
+ };
+
+ let source = os::open(args[1], fs::flags::RDONLY)!;
+ defer io::close(source)!;
+
+ const source = mbr::from(source)!;
+
+ const vol = cmd::openvol(vol);
+ let vol = gpt::from(vol)!;
+ defer {
+ gpt::chksums(vol);
+ gpt::commit(vol)!;
+ gpt::finish(vol);
+ };
+
+ rt::memcpy(vol.mbr, source.bootsector, size(mbr::bootsector));
+ for (let i = 0z; i < 4; i += 1) {
+ const entry = &source.bootsector.entries[i];
+ if (entry.lba_begin == 0 && entry.length == 0)
+ continue;
+
+ const reader = mbr::partstream_reader(source, entry)!;
+ const partlength = entry.length;
+
+ const part = gpt::allocate(vol, partlength) as *gpt::entry;
+
+ const writer = gpt::partstream_writer(vol, part)!;
+
+ io::copy(&writer, &reader)!;
+
+ vol.mbr.entries[i].lba_begin = part.lba_begin: u32;
+ vol.mbr.entries[i].length = (part.lba_end - part.lba_begin + 1): u32;
+ };
+
+ vol.mbr.entries[3] = mbr::entry {
+ part_type = 0xEE,
+ lba_begin = 0,
+ length = -1: u32,
+ ...
+ };
+};