Files
riscv64-kernel/crates/bffs/src/boot_sector.rs

168 lines
5.6 KiB
Rust

use io::Read;
use crate::io_ext::ReadLeExt;
#[derive(Debug, Clone, Copy)]
pub struct Fat32BootSector {
// --- Jump + OEM ---
pub jump_boot: [u8; 3],
pub oem_name: [u8; 8],
// --- BPB (BIOS Parameter Block) ---
pub bytes_per_sector: u16,
pub sectors_per_cluster: u8,
pub reserved_sector_count: u16,
pub num_fats: u8,
pub root_entry_count: u16,
pub total_sectors_16: u16,
pub media: u8,
pub fat_size_16: u16,
pub sectors_per_track: u16,
pub num_heads: u16,
pub hidden_sectors: u32,
pub total_sectors_32: u32,
// --- FAT32 Extended BPB ---
pub fat_size_32: u32,
pub ext_flags: u16,
pub fs_version: u16,
pub root_cluster: u32,
pub fs_info: u16,
pub bk_boot_sec: u16,
pub reserved: [u8; 12],
// --- FAT32 Drive Info ---
pub drive_number: u8,
pub reserved1: u8,
pub boot_signature: u8,
pub volume_id: u32,
pub volume_label: [u8; 11],
pub fs_type: [u8; 8],
// --- Boot code ---
pub boot_code: [u8; 420],
// --- Signature ---
pub boot_sector_signature: u16, // 0xAA55
}
impl core::fmt::Display for Fat32BootSector {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Fat32BootSector")
.field("jump_boot", &self.jump_boot)
.field("oem_name", &self.get_oem_name())
.field("bytes_per_sector", &self.bytes_per_sector)
.field("sectors_per_cluster", &self.sectors_per_cluster)
.field("reserved_sector_count", &self.reserved_sector_count)
.field("num_fats", &self.num_fats)
.field("root_entry_count", &self.root_entry_count)
.field("total_sectors_16", &self.total_sectors_16)
.field("media", &self.media)
.field("fat_size_16", &self.fat_size_16)
.field("sectors_per_track", &self.sectors_per_track)
.field("num_heads", &self.num_heads)
.field("hidden_sectors", &self.hidden_sectors)
.field("total_sectors_32", &self.total_sectors_32)
.field("fat_size_32", &self.fat_size_32)
.field("ext_flags", &self.ext_flags)
.field("fs_version", &self.fs_version)
.field("root_cluster", &self.root_cluster)
.field("fs_info", &self.fs_info)
.field("bk_boot_sec", &self.bk_boot_sec)
.field("reserved", &self.reserved)
.field("drive_number", &self.drive_number)
.field("reserved1", &self.reserved1)
.field("boot_signature", &self.boot_signature)
.field("volume_id", &self.volume_id)
.field("volume_label", &self.get_volume_label())
.field("fs_type", &self.get_fs_type())
.field("boot_code", &"[_; 420]")
.field("boot_sector_signature", &self.boot_sector_signature)
.finish()
}
}
impl Fat32BootSector {
pub fn get_oem_name(&self) -> Result<&str, core::str::Utf8Error> {
str::from_utf8(&self.oem_name)
}
pub fn get_volume_label(&self) -> Result<&str, core::str::Utf8Error> {
str::from_utf8(&self.volume_label)
}
pub fn get_fs_type(&self) -> Result<&str, core::str::Utf8Error> {
str::from_utf8(&self.fs_type)
}
}
impl Fat32BootSector {
pub fn deserialize<T: Read>(disk: &mut T) -> Result<Self, io::Error> {
let mut jump_boot = [0u8; _];
disk.read_exact(&mut jump_boot)?;
let mut oem_name = [0u8; _];
disk.read_exact(&mut oem_name)?;
let bytes_per_sector = disk.read_u16_le()?;
let sectors_per_cluster = disk.read_u8()?;
let reserved_sector_count = disk.read_u16_le()?;
let num_fats = disk.read_u8()?;
let root_entry_count = disk.read_u16_le()?;
let total_sectors_16 = disk.read_u16_le()?;
let media = disk.read_u8()?;
let fat_size_16 = disk.read_u16_le()?;
let sectors_per_track = disk.read_u16_le()?;
let num_heads = disk.read_u16_le()?;
let hidden_sectors = disk.read_u32_le()?;
let total_sectors_32 = disk.read_u32_le()?;
let fat_size_32 = disk.read_u32_le()?;
let ext_flags = disk.read_u16_le()?;
let fs_version = disk.read_u16_le()?;
let root_cluster = disk.read_u32_le()?;
let fs_info = disk.read_u16_le()?;
let bk_boot_sec = disk.read_u16_le()?;
let mut reserved = [0u8; _];
disk.read_exact(&mut reserved)?;
let drive_number = disk.read_u8()?;
let reserved1 = disk.read_u8()?;
let boot_signature = disk.read_u8()?;
let volume_id = disk.read_u32_le()?;
let mut volume_label = [0u8; _];
disk.read_exact(&mut volume_label)?;
let mut fs_type = [0u8; _];
disk.read_exact(&mut fs_type)?;
let mut boot_code = [0u8; _];
disk.read_exact(&mut boot_code)?;
let boot_sector_signature = disk.read_u16_le()?;
Ok(Self {
jump_boot,
oem_name,
bytes_per_sector,
sectors_per_cluster,
reserved_sector_count,
num_fats,
root_entry_count,
total_sectors_16,
media,
fat_size_16,
sectors_per_track,
num_heads,
hidden_sectors,
total_sectors_32,
fat_size_32,
ext_flags,
fs_version,
root_cluster,
fs_info,
bk_boot_sec,
reserved,
drive_number,
reserved1,
boot_signature,
volume_id,
volume_label,
fs_type,
boot_code,
boot_sector_signature,
})
}
}