2022-04-27 00:39:02 +08:00

192 lines
6.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file fat32.h
* @author fslongjin (longjin@RinGoTek.cn)
* @brief fat32文件系统
* @version 0.1
* @date 2022-04-19
*
* @copyright Copyright (c) 2022
*
*/
#pragma once
#include <filesystem/MBR.h>
#include <filesystem/VFS/VFS.h>
#define FAT32_MAX_PARTITION_NUM 128 // 系统支持的最大的fat32分区数量
/**
* @brief fat32文件系统引导扇区结构体
*
*/
struct fat32_BootSector_t
{
uint8_t BS_jmpBoot[3]; // 跳转指令
uint8_t BS_OEMName[8]; // 生产厂商名
uint16_t BPB_BytesPerSec; // 每扇区字节数
uint8_t BPB_SecPerClus; // 每簇扇区数
uint16_t BPB_RsvdSecCnt; // 保留扇区数
uint8_t BPB_NumFATs; // FAT表数量
uint16_t BPB_RootEntCnt; // 根目录文件数最大值
uint16_t BPB_TotSec16; // 16位扇区总数
uint8_t BPB_Media; // 介质描述符
uint16_t BPB_FATSz16; // FAT12/16每FAT扇区数
uint16_t BPB_SecPerTrk; // 每磁道扇区数
uint16_t BPB_NumHeads; // 磁头数
uint32_t BPB_HiddSec; // 隐藏扇区数
uint32_t BPB_TotSec32; // 32位扇区总数
uint32_t BPB_FATSz32; // FAT32每FAT扇区数
uint16_t BPB_ExtFlags; // 扩展标志
uint16_t BPB_FSVer; // 文件系统版本号
uint32_t BPB_RootClus; // 根目录起始簇号
uint16_t BPB_FSInfo; // FS info结构体的扇区号
uint16_t BPB_BkBootSec; // 引导扇区的备份扇区号
uint8_t BPB_Reserved0[12];
uint8_t BS_DrvNum; // int0x13的驱动器号
uint8_t BS_Reserved1;
uint8_t BS_BootSig; // 扩展引导标记
uint32_t BS_VolID; // 卷序列号
uint8_t BS_VolLab[11]; // 卷标
uint8_t BS_FilSysType[8]; // 文件系统类型
uint8_t BootCode[420]; // 引导代码、数据
uint16_t BS_TrailSig; // 结束标志0xAA55
} __attribute__((packed));
/**
* @brief fat32文件系统的FSInfo扇区结构体
*
*/
struct fat32_FSInfo_t
{
uint32_t FSI_LeadSig; // FS info扇区标志符 数值为0x41615252
uint8_t FSI_Reserved1[480]; // 保留使用全部置为0
uint32_t FSI_StrucSig; // 另一个标志符数值为0x61417272
uint32_t FSI_Free_Count; // 上一次记录的空闲簇数量,这是一个参考值
uint32_t FSI_Nxt_Free; // 空闲簇的起始搜索位置,这是为驱动程序提供的参考值
uint8_t FSI_Reserved2[12]; // 保留使用全部置为0
uint32_t FSI_TrailSig; // 结束标志数值为0xaa550000
} __attribute__((packed));
#define ATTR_READ_ONLY (1 << 0)
#define ATTR_HIDDEN (1 << 1)
#define ATTR_SYSTEM (1 << 2)
#define ATTR_VOLUME_ID (1 << 3)
#define ATTR_DIRECTORY (1 << 4)
#define ATTR_ARCHIVE (1 << 5)
#define ATTR_LONG_NAME (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID)
/**
* @brief fat32文件系统短目录项,大小为32bytes
*
*/
struct fat32_Directory_t
{
unsigned char DIR_Name[11];
unsigned char DIR_Attr; // 文件属性
unsigned char DIR_NTRes; // EXT|BASE => 8(BASE).3(EXT)
// BASE:LowerCase(8),UpperCase(0)
// EXT:LowerCase(16),UpperCase(0)
unsigned char DIR_CrtTimeTenth; // 文件创建的毫秒级时间戳
unsigned short DIR_CrtTime; // 文件创建时间
unsigned short DIR_CrtDate; // 文件创建日期
unsigned short DIR_LastAccDate; // 文件的最后访问日期
unsigned short DIR_FstClusHI; // 起始簇号高16bit
unsigned short DIR_WrtTime; // 最后写入时间
unsigned short DIR_WrtDate; // 最后写入日期
unsigned short DIR_FstClusLO; // 起始簇号低16bit
unsigned int DIR_FileSize; // 文件大小
} __attribute__((packed));
#define LOWERCASE_BASE (8)
#define LOWERCASE_EXT (16)
/**
* @brief fat32文件系统长目录项,大小为32bytes
*
*/
struct fat32_LongDirectory_t
{
unsigned char LDIR_Ord; // 长目录项的序号
unsigned short LDIR_Name1[5]; // 长文件名的第1-5个字符每个字符占2bytes
unsigned char LDIR_Attr; // 目录项属性必须为ATTR_LONG_NAME
unsigned char LDIR_Type; // 如果为0则说明这是长目录项的子项
unsigned char LDIR_Chksum; // 短文件名的校验和
unsigned short LDIR_Name2[6]; // 长文件名的第6-11个字符每个字符占2bytes
unsigned short LDIR_FstClusLO; // 必须为0
unsigned short LDIR_Name3[2]; // 长文件名的12-13个字符每个字符占2bytes
} __attribute__((packed));
/**
* @brief fat32文件系统的超级块信息结构体
*
*/
struct fat32_partition_info_t
{
uint16_t partition_id; // 全局fat32分区id
uint8_t ahci_ctrl_num;
uint8_t ahci_port_num;
uint8_t part_num; // 硬盘中的分区号
struct fat32_BootSector_t bootsector;
struct fat32_FSInfo_t fsinfo;
uint64_t fsinfo_sector_addr_infat;
uint64_t bootsector_bak_sector_addr_infat;
uint64_t starting_sector;
uint64_t sector_count;
uint64_t sec_per_clus; // 每簇扇区数
uint64_t bytes_per_sec; // 每扇区字节数
uint64_t bytes_per_clus; // 每簇字节数
uint64_t first_data_sector; // 数据区起始扇区号
uint64_t FAT1_base_sector; // FAT1表的起始簇号
uint64_t FAT2_base_sector; // FAT2表的起始簇号
uint64_t sec_per_FAT; // 每FAT表扇区数
uint64_t NumFATs; // FAT表数
};
typedef struct fat32_partition_info_t fat32_sb_info_t;
struct fat32_inode_info_t
{
uint64_t first_clus;
uint64_t dEntry_location_clus; // dEntry struct in cluster (0 is root, 1 is invalid)
uint64_t dEntry_location_clus_offset; // dEntry struct offset in cluster
uint16_t create_date;
uint16_t create_time;
uint16_t write_time;
uint16_t write_date;
};
typedef struct fat32_inode_info_t fat32_inode_info_t;
/**
* @brief 注册指定磁盘上的指定分区的fat32文件系统
*
* @param ahci_ctrl_num ahci控制器编号
* @param ahci_port_num ahci控制器端口编号
* @return struct vfs_super_block_t * 文件系统的超级块
*/
struct vfs_superblock_t *fat32_register_partition(uint8_t ahci_ctrl_num, uint8_t ahci_port_num, uint8_t part_num);
/**
* @brief 创建fat32文件系统的超级块
*
* @param DPTE 磁盘分区表entry
* @param DPT_type 磁盘分区表类型
* @param buf fat32文件系统的引导扇区
* @return struct vfs_superblock_t* 创建好的超级块
*/
struct vfs_superblock_t *fat32_read_superblock(void *DPTE, uint8_t DPT_type, void *buf, int8_t ahci_ctrl_num, int8_t ahci_port_num, int8_t part_num);
long fat32_create(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dentry, int mode);
void fat32_init();