···11-ocaml-mbr
22-=========
11+# mbr
22+33+A library to manipulate Master Boot Records in pure OCaml.
44+55+## Overview
66+77+Pure OCaml library for reading and writing Master Boot Records (MBR). Supports
88+creating disk images with primary partition tables, CHS geometry translation,
99+and streaming I/O via bytesrw.
1010+1111+## Features
1212+1313+- MBR header and partition table encoding/decoding
1414+- Up to 4 primary partitions with overlap and bootable flag validation
1515+- CHS geometry synthesis for pre-LBA compatibility
1616+- Wire codecs for zero-copy partition entry access
1717+- Streaming I/O with bytesrw readers/writers
1818+- Pretty-printer
31944-A library for manipulating Master Boot Records. The
55-primary purposes of this library are:
66- 1. to create bootable disk images creating
77- [mirage](http://www.openmirage.org/) kernels
88- 2. for mirage kernels to read the partition tables on
99- attached disks
2020+## Installation
10211111-Usage
1212------
1313-Define a single partition as follows:
1422```
1515- let disk_length_bytes = Int32.(mul (mul 16l 1024l) 1024l) in
1616- let disk_length_sectors = Int32.(div disk_length_bytes 512l) in
2323+opam install mbr
2424+```
17251818- let start_sector = 2048l in
1919- let length_sectors = Int32.sub disk_length_sectors start_sector in
2020- let partition = Mbr.Partition.make ~active:true ~ty:6 start_sector length_sectors in
2121- let mbr = Mbr.make [ partition ] in
2626+## Usage
2727+2828+### Creating an MBR
2929+3030+```ocaml
3131+(* Create a partition: FAT16 (type 6), starting at sector 2048, 32MB *)
3232+match Mbr.Partition.make ~active:true ~partition_type:6 2048l 65536l with
3333+| Error e -> failwith e
3434+| Ok part ->
3535+ match Mbr.v [ part ] with
3636+ | Error e -> failwith e
3737+ | Ok mbr -> Fmt.pr "%a@." Mbr.pp mbr
2238```
2323-You can write the MBR to sector zero of a block device ```B``` as follows:
3939+4040+### Serialization
4141+4242+```ocaml
4343+(* Write to string *)
4444+let bytes = Mbr.to_string mbr
4545+4646+(* Read from string *)
4747+match Mbr.of_string bytes with
4848+| Ok mbr -> List.iter (fun p ->
4949+ Printf.printf "Partition: start=%Ld, size=%Ld\n"
5050+ (Mbr.Partition.sector_start p)
5151+ (Mbr.Partition.size_sectors p))
5252+ (Mbr.partitions mbr)
5353+| Error e -> failwith e
2454```
2525- B.connect id >>= fun device ->
2626- let sector = Cstruct.create 512 in
2727- Mbr.marshal sector mbr;
2828- B.write device 0L [ sector ] >>= fun () ->
2929- ...
5555+5656+### Streaming I/O with bytesrw
5757+5858+```ocaml
5959+(* Read *)
6060+match Mbr.read reader with
6161+| Ok mbr -> Fmt.pr "%a@." Mbr.pp mbr
6262+| Error e -> failwith e
6363+6464+(* Write *)
6565+Mbr.write writer mbr
6666+```
6767+6868+### CHS Geometry
6969+7070+```ocaml
7171+(* Synthesise geometry for a 4GB disk *)
7272+match Mbr.Geometry.of_lba_size 8388608L with
7373+| Ok geom -> Printf.printf "C=%d H=%d S=%d\n"
7474+ geom.cylinders geom.heads geom.sectors
7575+| Error e -> failwith e
3076```
31773232-To do items
3333------------
7878+## API
34793535-* Implement tools to manipulate MBR-formatted disk images
3636- to construct, inspect or fill partitions that can later
3737- be used in Mirage unikernels.
8080+### Partition
8181+8282+- `Mbr.Partition.make` -- Create a partition (`~partition_type:int -> int32 -> int32 -> (t, string) result`)
8383+- `Mbr.Partition.make'` -- Create a partition with int64 args
8484+- `Mbr.Partition.sector_start` -- LBA start as int64
8585+- `Mbr.Partition.size_sectors` -- Size in sectors as int64
8686+- `Mbr.Partition.codec` -- Wire codec for 16-byte partition entry
8787+8888+### MBR
8989+9090+- `Mbr.v` -- Create an MBR with up to 4 partitions (validates overlaps, active flags)
9191+- `Mbr.partitions` -- Extract partition list
9292+- `Mbr.pp` -- Pretty-print
9393+- `Mbr.sizeof` -- Size in bytes (512)
9494+- `Mbr.default_partition_start` -- Default first partition offset
9595+9696+### Serialization
9797+9898+- `Mbr.of_string` / `Mbr.to_string` -- String-based I/O
9999+- `Mbr.read` / `Mbr.write` -- Bytesrw streaming I/O
100100+101101+### Geometry
102102+103103+- `Mbr.Geometry.of_lba_size` -- Synthesise CHS from sector count
104104+- `Mbr.Geometry.to_chs` -- Convert LBA offset to CHS
105105+106106+## Requirements
107107+108108+- OCaml >= 5.1
109109+- bytesrw, wire, fmt
110110+111111+## Licence
112112+113113+ISC