diff options
| author | Alejandro Sior <aho@sior.be> | 2022-06-18 10:40:06 +0200 |
|---|---|---|
| committer | Alejandro Sior <aho@sior.be> | 2022-06-18 10:40:06 +0200 |
| commit | d6181b5e4f6f2dc72907e9f2e73db9ce0075cddd (patch) | |
| tree | bda9e927101a267102dae6eb214e507b0bd5d9ab /mbr | |
| parent | 12577f3445df86023ba0cbe2462d55ea5dcafe20 (diff) | |
gptman: implement convert
Diffstat (limited to 'mbr')
| -rw-r--r-- | mbr/mbr.ha | 40 |
1 files changed, 36 insertions, 4 deletions
@@ -8,24 +8,56 @@ def mbr_lba: size = 0; export type nombr = !void; export type mbr = struct { + bootsector_sec: sector::sector, + bootsector: *bootsector +}; + +export type bootsector = struct { @offset(0) bootstrap: [440]u8, @offset(440) udid: u32, @offset(444) reserved: u16, - @offset(446) entries: [4]mbr_entry, + @offset(446) entries: [4]entry, @offset(510) magic: u16, }; -export type mbr_entry = struct { +export type entry = struct { @offset(0) attributes: u8, @offset(4) part_type: u8, @offset(8) lba_begin: u32, - @offset(12) lba_end: u32, + @offset(12) length: u32, }; -export fn validate(self: *mbr) bool = { +export fn bootsector_validate(self: *bootsector) bool = { if (self.magic != 0xaa55) { return false; }; return true; }; + +export fn from(fd: io::file) (*mbr | nombr | io::error) = { + const bootsector_sec = sector::map(fd, 0, 1); + sector::fetch(&bootsector_sec)?; + + const bootsector = bootsector_sec.buf: *[*]u8: *bootsector; + if (!bootsector_validate(bootsector)) { + sector::finish(&bootsector_sec); + return nombr; + }; + + let self = alloc(mbr { + bootsector_sec = bootsector_sec, + bootsector = bootsector + }); + + return self; +}; + +export fn partstream_reader(self: *mbr, entry: *entry) (io::limitstream | io::error) = { + const fd = self.bootsector_sec.fd; + const part = entry.lba_begin * sector::sector_length; + const length = entry.length * sector::sector_length; + + io::seek(fd, part: io::off, io::whence::SET)?; + return io::limitreader(fd, length); +}; |
