summaryrefslogtreecommitdiff
path: root/mbr
diff options
context:
space:
mode:
authorAlejandro Sior <aho@sior.be>2022-06-15 17:42:40 +0200
committerAlejandro Sior <aho@sior.be>2022-06-15 17:42:40 +0200
commit3c8602ee9f04991e1d60b8d6504e12296ca671d9 (patch)
tree1be941405e224be61ce1f2c9116cc5f05bc13e01 /mbr
gptman: add files
Diffstat (limited to 'mbr')
-rw-r--r--mbr/mbr.ha50
1 files changed, 50 insertions, 0 deletions
diff --git a/mbr/mbr.ha b/mbr/mbr.ha
new file mode 100644
index 0000000..ceb115f
--- /dev/null
+++ b/mbr/mbr.ha
@@ -0,0 +1,50 @@
+use io;
+
+use sector;
+use errors;
+
+def mbr_lba: size = 0;
+
+export type nombr = !void;
+
+export type mbr = struct {
+ @offset(0) bootstrap: [440]u8,
+ @offset(440) udid: u32,
+ @offset(444) reserved: u16,
+ @offset(446) entries: [4]mbr_entry,
+ @offset(510) magic: u16,
+};
+
+export type mbr_entry = struct {
+ @offset(0) attributes: u8,
+ @offset(4) part_type: u8,
+ @offset(8) lba_begin: u32,
+ @offset(12) lba_end: u32,
+};
+
+export fn validate(self: *mbr) bool = {
+ if (self.magic != 0xaa55) {
+ return false;
+ };
+
+ return true;
+};
+
+// Gets a handle to the MBR of a partition.
+// Return value is returned to user. Resource should be freed with mbr::finish.
+export fn from(fd: io::file) (*mbr | nombr | errors::error) = {
+ const self = io::mmap(null, sector::length, io::prot::READ | io::prot::WRITE, io::mflags::SHARED, fd, sector::lba(mbr_lba))!: *mbr;
+
+ if (!validate(self)) {
+ io::munmap(self, sector::length)?;
+ return nombr;
+ };
+
+ return self;
+};
+
+// Frees the resources associated with the MBR partition.
+// User revokes ownership.
+export fn finish(self: *mbr) (void | errors::error) = {
+ io::munmap(self, sector::length)?;
+};