diff --git a/kernel/src/filesystem/fat/bpb.rs b/kernel/src/filesystem/fat/bpb.rs index 6a82142b..69eb65f4 100644 --- a/kernel/src/filesystem/fat/bpb.rs +++ b/kernel/src/filesystem/fat/bpb.rs @@ -8,7 +8,7 @@ use crate::{ libs::vec_cursor::VecCursor, }; -use super::fs::Cluster; +use super::fs::{Cluster, FATFileSystem}; /// 对于所有的FAT文件系统都适用的Bios Parameter Block结构体 #[derive(Debug, Clone, Copy, Default)] @@ -179,6 +179,45 @@ impl FATType { } } +impl BiosParameterBlockLegacy { + /// @brief 验证FAT12/16 BPB的信息是否合法 + fn validate(&self, _bpb: &BiosParameterBlock) -> Result<(), i32> { + return Ok(()); + } +} + +impl BiosParameterBlockFAT32 { + /// @brief 验证BPB32的信息是否合法 + fn validate(&self, bpb: &BiosParameterBlock) -> Result<(), i32> { + if bpb.fat_size_16 != 0 { + kerror!("Invalid fat_size_16 value in BPB (should be zero for FAT32)"); + return Err(-(EINVAL as i32)); + } + + if bpb.root_entries_cnt != 0 { + kerror!("Invalid root_entries value in BPB (should be zero for FAT32)"); + return Err(-(EINVAL as i32)); + } + + if bpb.total_sectors_16 != 0 { + kerror!("Invalid total_sectors_16 value in BPB (should be zero for FAT32)"); + return Err(-(EINVAL as i32)); + } + + if self.fat_size_32 == 0 { + kerror!("Invalid fat_size_32 value in BPB (should be non-zero for FAT32)"); + return Err(-(EINVAL as i32)); + } + + if self.fs_version != 0 { + kerror!("Unknown FAT FS version"); + return Err(-(EINVAL as i32)); + } + + return Ok(()); + } +} + impl BiosParameterBlock { pub fn new(partition: Arc) -> Result { let mut v = Vec::with_capacity(LBA_SIZE); @@ -230,9 +269,6 @@ impl BiosParameterBlock { // 读取尾部的启动扇区标志 bpb.trail_sig = cursor.read_u16()?; - // 验证BPB32的信息是否合法 - bpb.validate(&bpb32)?; - // 计算根目录项占用的空间(单位:字节) let root_sectors = ((bpb.root_entries_cnt as u32 * 32) + (bpb.bytes_per_sector as u32 - 1)) / (bpb.bytes_per_sector as u32); @@ -258,19 +294,25 @@ impl BiosParameterBlock { let count_clusters = data_sectors / (bpb.sector_per_cluster as u32); // 设置FAT类型 - bpb.fat_type = if count_clusters < 4085 { + bpb.fat_type = if count_clusters < FATFileSystem::FAT12_MAX_CLUSTER { FATType::FAT12(BiosParameterBlockLegacy::default()) - } else if count_clusters < 65525 { + } else if count_clusters <= FATFileSystem::FAT16_MAX_CLUSTER { FATType::FAT16(BiosParameterBlockLegacy::default()) - } else { + } else if count_clusters < FATFileSystem::FAT32_MAX_CLUSTER { FATType::FAT32(bpb32) + } else { + // 都不符合条件,报错 + return Err(-(EINVAL as i32)); }; + // 验证BPB的信息是否合法 + bpb.validate()?; + return Ok(bpb); } - /// @brief 验证BPB32的信息是否合法 - pub fn validate(&self, bpb32: &BiosParameterBlockFAT32) -> Result<(), i32> { + /// @brief 验证BPB的信息是否合法 + pub fn validate(&self) -> Result<(), i32> { // 校验每扇区字节数是否合法 if self.bytes_per_sector.count_ones() != 1 { kerror!("Invalid bytes per sector(not a power of 2)"); @@ -283,8 +325,6 @@ impl BiosParameterBlock { return Err(-(EINVAL as i32)); } - let is_fat32 = self.is_fat32(); - if self.rsvd_sec_cnt < 1 { kerror!("Invalid rsvd_sec_cnt value in BPB"); return Err(-(EINVAL as i32)); @@ -295,42 +335,26 @@ impl BiosParameterBlock { return Err(-(EINVAL as i32)); } - if is_fat32 && self.root_entries_cnt != 0 { - kerror!("Invalid root_entries value in BPB (should be zero for FAT32)"); - return Err(-(EINVAL as i32)); - } - - if is_fat32 && self.total_sectors_16 != 0 { - kerror!("Invalid total_sectors_16 value in BPB (should be zero for FAT32)"); - return Err(-(EINVAL as i32)); - } - if (self.total_sectors_16 == 0) && (self.total_sectors_32 == 0) { kerror!("Invalid BPB (total_sectors_16 or total_sectors_32 should be non-zero)"); return Err(-(EINVAL as i32)); } - if is_fat32 && bpb32.fat_size_32 == 0 { - kerror!("Invalid fat_size_32 value in BPB (should be non-zero for FAT32)"); - return Err(-(EINVAL as i32)); - } - - if bpb32.fs_version != 0 { - kerror!("Unknown FAT FS version"); - return Err(-(EINVAL as i32)); - } + let fat_size = match self.fat_type { + FATType::FAT32(bpb32) => { + bpb32.validate(self)?; + bpb32.fat_size_32 + } + FATType::FAT16(bpb_legacy) | FATType::FAT12(bpb_legacy) => { + bpb_legacy.validate(self)?; + self.fat_size_16 as u32 + } + }; let root_sectors = ((self.root_entries_cnt as u32 * 32) + (self.bytes_per_sector as u32 - 1)) / (self.bytes_per_sector as u32); - // 每FAT扇区数 - let fat_size = if self.fat_size_16 != 0 { - self.fat_size_16 as u32 - } else { - bpb32.fat_size_32 - }; - // 当前分区总扇区数 let total_sectors = if self.total_sectors_16 != 0 { self.total_sectors_16 as u32 @@ -341,31 +365,15 @@ impl BiosParameterBlock { let first_data_sector = (self.rsvd_sec_cnt as u32) + (self.num_fats as u32) * fat_size + root_sectors; - // 数据区扇区数 - let data_sectors = total_sectors - first_data_sector; - // 总的数据簇数量(向下对齐) - let count_clusters = data_sectors / (self.sector_per_cluster as u32); - // 总扇区数应当大于第一个数据扇区的扇区号 if total_sectors <= first_data_sector { kerror!("Total sectors lesser than first data sector"); return Err(-(EINVAL as i32)); } - // 检查文件系统类型与总的数据簇数量的关系是否合法 - if (is_fat32 && (count_clusters < 65525)) || ((!is_fat32) && (count_clusters >= 65525)) { - kerror!("FAT determination using tot_sec_16 and count_cluster differs"); - return Err(-(EINVAL as i32)); - } return Ok(()); } - /// @brief 判断当前是否为fat32的bpb - fn is_fat32(&self) -> bool { - // fat32的bpb,这个字段是0 - return self.total_sectors_16 == 0; - } - pub fn get_volume_id(&self) -> u32 { match self.fat_type { FATType::FAT12(f) | FATType::FAT16(f) => { diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index 8e47dd4d..e4aea845 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -244,6 +244,13 @@ impl FileSystem for FATFileSystem { } impl FATFileSystem { + /// FAT12允许的最大簇号 + pub const FAT12_MAX_CLUSTER: u32 = 0xFF5; + /// FAT16允许的最大簇号 + pub const FAT16_MAX_CLUSTER: u32 = 0xFFF5; + /// FAT32允许的最大簇号 + pub const FAT32_MAX_CLUSTER: u32 = 0x0FFFFFF7; + pub fn new(partition: Arc) -> Result, i32> { let bpb = BiosParameterBlock::new(partition.clone())?;