Crate gpt_disk_io

source ·
Expand description

Library for reading and writing GPT disk data structures through a block IO interface.

This crate adds a convenient interface for reading and writing the GPT types defined in the gpt_disk_types crate to a Disk. The Disk is represented by the BlockIo trait, which allows this library to be no_std. The BlockIo trait is designed to be compatible with very simple block APIs, such as EFI_BLOCK_IO_PROTOCOL.

The BlockIoAdapter type allows the disk to be backed by simple byte-oriented storage backends, such as &mut [u8] and File (the latter requires the std feature).

Features

  • alloc: Enables Vec implementation of BlockIoAdapter.
  • std: Enables std::io implementations of BlockIoAdapter, as well as std::error::Error implementations for all of the error types. Off by default.

Examples

Construct a GPT disk in-memory backed by a Vec:

use gpt_disk_io::{BlockIoAdapter, BlockIo, Disk, DiskError};
use gpt_disk_types::{
    guid, BlockSize, Crc32, GptHeader, GptPartitionEntry,
    GptPartitionEntryArray, GptPartitionType, LbaLe, U32Le,
};

// Space for a 4MiB disk.
let mut disk_storage = vec![0; 4 * 1024 * 1024];

// Standard 512-byte block size.
let bs = BlockSize::BS_512;

// `BlockIoAdapter` implements the `BlockIo` trait which is used by
// the `Disk` type for reading and writing.
let block_io = BlockIoAdapter::new(disk_storage.as_mut_slice(), bs);

let mut disk = Disk::new(block_io)?;

// Manually construct the header and partition entries.
let primary_header = GptHeader {
    header_crc32: Crc32(U32Le::from_u32(0xa4877843)),
    my_lba: LbaLe::from_u64(1),
    alternate_lba: LbaLe::from_u64(8191),
    first_usable_lba: LbaLe::from_u64(34),
    last_usable_lba: LbaLe::from_u64(8158),
    disk_guid: guid!("57a7feb6-8cd5-4922-b7bd-c78b0914e870"),
    partition_entry_lba: LbaLe::from_u64(2),
    number_of_partition_entries: U32Le::from_u32(128),
    partition_entry_array_crc32: Crc32(U32Le::from_u32(0x9206adff)),
    ..Default::default()
};
let secondary_header = GptHeader {
    header_crc32: Crc32(U32Le::from_u32(0xdbeb4c13)),
    my_lba: LbaLe::from_u64(8191),
    alternate_lba: LbaLe::from_u64(1),
    partition_entry_lba: LbaLe::from_u64(8159),
    ..primary_header
};
let partition_entry = GptPartitionEntry {
    partition_type_guid: GptPartitionType(guid!(
        "ccf0994f-f7e0-4e26-a011-843e38aa2eac"
    )),
    unique_partition_guid: guid!("37c75ffd-8932-467a-9c56-8cf1f0456b12"),
    starting_lba: LbaLe::from_u64(2048),
    ending_lba: LbaLe::from_u64(4096),
    attributes: Default::default(),
    name: "hello world!".parse().unwrap(),
};

// Create a buffer the length of one block. A `Vec` is used here,
// but any mutable byte slice with the right length will do.
let mut block_buf = vec![0u8; bs.to_usize().unwrap()];

// Write out the protective MBR and GPT headers. Note that without
// the protective MBR, some tools won't recognize the disk as GPT.
disk.write_protective_mbr(&mut block_buf)?;
disk.write_primary_gpt_header(&primary_header, &mut block_buf)?;
disk.write_secondary_gpt_header(&secondary_header, &mut block_buf)?;

// Construct the partition entry array.
let layout = primary_header.get_partition_entry_array_layout().unwrap();
let mut bytes =
    vec![0; layout.num_bytes_rounded_to_block_as_usize(bs).unwrap()];
let mut entry_array =
    GptPartitionEntryArray::new(layout, bs, &mut bytes).unwrap();
*entry_array.get_partition_entry_mut(0).unwrap() = partition_entry;

// Write the primary partition entry array.
disk.write_gpt_partition_entry_array(&entry_array)?;

// Write the secondary partition entry array.
entry_array.set_start_lba(secondary_header.partition_entry_lba.into());
disk.write_gpt_partition_entry_array(&entry_array)?;

// Ensure all writes are flushed. This is not needed with the slice
// backend, but is good practice for "real" IO. (The disk will also
// flush when dropped, but any errors at that point are ignored.)
disk.flush()?;

Re-exports

Structs

  • Adapter for types that can act as storage, but don’t have a block size. This is used to provide BlockIo impls for byte slices, files, and various other types.
  • Read and write GPT disk data.

Enums

Traits