summaryrefslogtreecommitdiff
path: root/mbr/mbr.ha
diff options
context:
space:
mode:
Diffstat (limited to 'mbr/mbr.ha')
-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)?;
+};