🆕 在fat32文件系统中按照路径寻找文件

This commit is contained in:
fslongjin
2022-04-20 19:55:36 +08:00
parent db8b4a4877
commit 9b382dab60
10 changed files with 590 additions and 53 deletions

20
kernel/filesystem/MBR.c Normal file
View File

@ -0,0 +1,20 @@
#include "MBR.h"
#include <common/kprint.h>
#include <driver/disk/ahci/ahci.h>
struct MBR_disk_partition_table_t MBR_partition_tables[MBR_MAX_AHCI_CTRL_NUM][MBR_MAX_AHCI_PORT_NUM] = {0};
/**
* @brief 读取磁盘的分区表
*
* @param ahci_ctrl_num ahci控制器编号
* @param ahci_port_num ahci端口编号
*/
struct MBR_disk_partition_table_t *MBR_read_partition_table(uint8_t ahci_ctrl_num, uint8_t ahci_port_num)
{
unsigned char buf[512];
memset(buf, 0, 512);
ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, 0, 1, (uint64_t)&buf, ahci_ctrl_num, ahci_port_num);
MBR_partition_tables[ahci_ctrl_num][ahci_port_num] = *(struct MBR_disk_partition_table_t *)buf;
return &MBR_partition_tables[ahci_ctrl_num][ahci_port_num];
}

View File

@ -11,34 +11,47 @@
#pragma once
#include <common/glib.h>
#define MBR_MAX_AHCI_CTRL_NUM 4 // 系统支持的最大的ahci控制器数量
#define MBR_MAX_AHCI_PORT_NUM 32 // 系统支持的每个ahci控制器对应的MBR磁盘数量对应ahci磁盘号
/**
* @brief MBR硬盘分区表项的结构
*
*/
struct MBR_disk_partition_table_entry_t
{
uint8_t flags; // 引导标志符,标记此分区为活动分区
uint8_t starting_head; // 起始磁头号
uint8_t flags; // 引导标志符,标记此分区为活动分区
uint8_t starting_head; // 起始磁头号
uint16_t starting_sector : 6, // 起始扇区号
starting_cylinder : 10; // 起始柱面号
uint8_t type; // 分区类型ID
uint8_t ending_head; // 结束磁头号
uint8_t type; // 分区类型ID
uint8_t ending_head; // 结束磁头号
uint16_t ending_sector : 6, // 结束扇区号
ending_cylinder : 10; // 结束柱面号
uint16_t ending_sector:6, // 结束扇区号
ending_cylinder:10; // 结束柱面号
uint32_t starting_LBA; // 起始逻辑扇区
uint32_t total_sectors; // 分区占用的磁盘扇区数
}__attribute__((packed));
} __attribute__((packed));
/**
* @brief MBR磁盘分区表结构体
*
*
*/
struct MBR_disk_partition_table_t
{
uint8_t reserved[446];
struct MBR_disk_partition_table_entry_t DPTE[4]; // 磁盘分区表项
struct MBR_disk_partition_table_entry_t DPTE[4]; // 磁盘分区表项
uint16_t BS_TrailSig;
}__attribute__((packed));
} __attribute__((packed));
extern struct MBR_disk_partition_table_t MBR_partition_tables[MBR_MAX_AHCI_CTRL_NUM][MBR_MAX_AHCI_PORT_NUM]; // 导出全局的MBR磁盘分区表
/**
* @brief 读取磁盘的分区表
*
* @param ahci_ctrl_num ahci控制器编号
* @param ahci_port_num ahci端口编号
*/
struct MBR_disk_partition_table_t *MBR_read_partition_table(uint8_t ahci_ctrl_num, uint8_t ahci_port_num);

View File

@ -1,42 +1,444 @@
#include "fat32.h"
#include <common/kprint.h>
#include <driver/disk/ahci/ahci.h>
#include <filesystem/MBR.h>
#include <process/spinlock.h>
#include <mm/slab.h>
struct fat32_partition_info_t fat32_part_info[FAT32_MAX_PARTITION_NUM] = {0};
static int total_fat32_parts = 0;
static int max_fat32_parts_id = -1;
static uint64_t fat32_part_info_bmp[FAT32_MAX_PARTITION_NUM / 64 + 1] = {0};
static spinlock_t fat32_part_reg_lock;
/**
* @brief 读取指定磁盘上的第0个分区的fat32文件系统
*
* @param disk_num
* @brief 注册指定磁盘上的指定分区的fat32文件系统
*
* @param ahci_ctrl_num ahci控制器编号
* @param ahci_port_num ahci控制器端口编号
* @param part_num 磁盘分区编号
*
* @return int 全局fat32分区id
*/
void fat32_FS_init(int disk_num)
int fat32_register_partition(uint8_t ahci_ctrl_num, uint8_t ahci_port_num, uint8_t part_num)
{
int i;
unsigned char buf[512];
struct MBR_disk_partition_table_t DPT;
struct fat32_BootSector_t fat32_bootsector;
struct fat32_FSInfo_t fat32_fsinfo;
for (int i = 0; i <= max_fat32_parts_id; ++i)
{
if (fat32_part_info_bmp[i / 64] & (1 << (i % 64)))
{
// 已经注册
if (ahci_ctrl_num == fat32_part_info[i].ahci_ctrl_num && ahci_port_num == fat32_part_info[i].ahci_port_num && part_num == fat32_part_info[i].part_num)
return i;
}
}
// 注册分区
spin_lock(&fat32_part_reg_lock);
int current_part_id;
for (int i = 0; i <= max_fat32_parts_id; ++i)
{
if ((fat32_part_info_bmp[i / 64] & (1 << (i % 64))) == 0)
{
current_part_id = i;
break;
}
}
++max_fat32_parts_id;
current_part_id = max_fat32_parts_id;
fat32_part_info_bmp[current_part_id / 64] |= (1 << (current_part_id % 64));
spin_unlock(&fat32_part_reg_lock);
fat32_part_info[current_part_id].ahci_ctrl_num = ahci_ctrl_num;
fat32_part_info[current_part_id].ahci_port_num = ahci_port_num;
fat32_part_info[current_part_id].part_num = part_num;
fat32_part_info[current_part_id].partition_id = current_part_id;
struct MBR_disk_partition_table_t *DPT = MBR_read_partition_table(ahci_ctrl_num, ahci_port_num);
memset(buf, 0, 512);
ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, 0, 1, (uint64_t)&buf, 0, 0);
DPT = *(struct MBR_disk_partition_table_t *)buf;
// for(i = 0 ;i < 512 ; i++)
// color_printk(PURPLE,WHITE,"%02x",buf[i]);
printk_color(ORANGE, BLACK, "DPTE[0] start_LBA:%#018lx\ttype:%#018lx\n", DPT.DPTE[0].starting_LBA, DPT.DPTE[0].type);
printk_color(ORANGE, BLACK, "DPTE[0] start_LBA:%#018lx\ttype:%#018lx\n", DPT->DPTE[part_num].starting_LBA, DPT->DPTE[part_num].type);
memset(buf, 0, 512);
ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, DPT.DPTE[0].starting_LBA, 1, (uint64_t)&buf, 0, 0);
ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, DPT->DPTE[part_num].starting_LBA, 1, (uint64_t)&buf, ahci_ctrl_num, ahci_port_num);
fat32_bootsector = *(struct fat32_BootSector_t *)buf;
// for(i = 0 ;i < 512 ; i++)
// printk_color(PURPLE,WHITE,"%02x",buf[i]);
printk_color(ORANGE, BLACK, "FAT32 Boot Sector\n\tBPB_FSInfo:%#018lx\n\tBPB_BkBootSec:%#018lx\n\tBPB_TotSec32:%#018lx\n", fat32_bootsector.BPB_FSInfo, fat32_bootsector.BPB_BkBootSec, fat32_bootsector.BPB_TotSec32);
fat32_part_info[current_part_id].bootsector = *(struct fat32_BootSector_t *)buf;
// 计算数据区起始扇区号
fat32_part_info[current_part_id].first_data_sector = DPT->DPTE[part_num].starting_LBA + fat32_part_info[current_part_id].bootsector.BPB_RsvdSecCnt +
fat32_part_info[current_part_id].bootsector.BPB_FATSz32 * fat32_part_info[current_part_id].bootsector.BPB_NumFATs;
// 计算FAT1的起始扇区号
fat32_part_info[current_part_id].FAT1_base_sector = DPT->DPTE[part_num].starting_LBA + fat32_part_info[current_part_id].bootsector.BPB_RsvdSecCnt;
// 计算FAT2的起始扇区号
fat32_part_info[current_part_id].FAT2_base_sector = fat32_part_info[current_part_id].FAT1_base_sector + fat32_part_info[current_part_id].bootsector.BPB_FATSz32;
// 计算每个簇的大小
fat32_part_info[current_part_id].bytes_per_clus = fat32_part_info[current_part_id].bootsector.BPB_BytesPerSec * fat32_part_info[current_part_id].bootsector.BPB_SecPerClus;
kdebug("fat32_part_info[current_part_id].FAT1_base_sector=%#018lx", fat32_part_info[current_part_id].FAT1_base_sector);
printk_color(ORANGE, BLACK, "FAT32 Boot Sector\n\tBPB_FSInfo:%#018lx\n\tBPB_BkBootSec:%#018lx\n\tBPB_TotSec32:%#018lx\n", fat32_part_info[current_part_id].bootsector.BPB_FSInfo, fat32_part_info[current_part_id].bootsector.BPB_BkBootSec, fat32_part_info[current_part_id].bootsector.BPB_TotSec32);
memset(buf, 0, 512);
ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, DPT.DPTE[0].starting_LBA+ fat32_bootsector.BPB_FSInfo, 1, (uint64_t)&buf, 0, 0);
ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, DPT->DPTE[part_num].starting_LBA + fat32_part_info[current_part_id].bootsector.BPB_FSInfo, 1, (uint64_t)&buf, ahci_ctrl_num, ahci_port_num);
fat32_fsinfo = *(struct fat32_FSInfo_t *)buf;
fat32_part_info[current_part_id].fsinfo = *(struct fat32_FSInfo_t *)buf;
// for(i = 0 ;i < 512 ; i++)
// printk_color(PURPLE,WHITE,"%02x",buf[i]);
printk_color(ORANGE, BLACK, "FAT32 FSInfo\n\tFSI_LeadSig:%#018lx\n\tFSI_StrucSig:%#018lx\n\tFSI_Free_Count:%#018lx\n", fat32_fsinfo.FSI_LeadSig, fat32_fsinfo.FSI_StrucSig, fat32_fsinfo.FSI_Free_Count);
printk_color(ORANGE, BLACK, "FAT32 FSInfo\n\tFSI_LeadSig:%#018lx\n\tFSI_StrucSig:%#018lx\n\tFSI_Free_Count:%#018lx\n", fat32_part_info[current_part_id].fsinfo.FSI_LeadSig, fat32_part_info[current_part_id].fsinfo.FSI_StrucSig, fat32_part_info[current_part_id].fsinfo.FSI_Free_Count);
kdebug("fat32_part_info[part_id].bootsector.BPB_RootClus = %#018lx", fat32_part_info[current_part_id].bootsector.BPB_RootClus);
return current_part_id;
}
/**
* @brief 读取指定簇的FAT表项
*
* @param part_id 分区id
* @param cluster
* @return uint32_t 下一个簇的簇号
*/
uint32_t fat32_read_FAT_entry(uint32_t part_id, uint32_t cluster)
{
uint32_t fat_ent_per_sec = (fat32_part_info[part_id].bootsector.BPB_BytesPerSec >> 2); // 该值应为2的n次幂
uint32_t buf[256];
memset(buf, 0, fat32_part_info[part_id].bootsector.BPB_BytesPerSec);
ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, fat32_part_info[part_id].FAT1_base_sector + (cluster / fat_ent_per_sec), 1, (uint64_t)&buf, fat32_part_info[part_id].ahci_ctrl_num, fat32_part_info[part_id].ahci_port_num);
uint32_t ret = buf[cluster & (fat_ent_per_sec - 1)] & 0x0fffffff;
return ret;
}
/**
* @brief 写入指定簇的FAT表项
*
* @param part_id 分区id
* @param cluster
* @param value 要写入该fat表项的值
* @return uint32_t 下一个簇的簇号
*/
uint32_t fat32_write_FAT_entry(uint32_t part_id, uint32_t cluster, uint32_t value)
{
uint32_t fat_ent_per_sec = (fat32_part_info[part_id].bootsector.BPB_BytesPerSec >> 2); // 该值应为2的n次幂
uint32_t buf[256];
memset(buf, 0, fat32_part_info[part_id].bootsector.BPB_BytesPerSec);
ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, fat32_part_info[part_id].FAT1_base_sector + (cluster / fat_ent_per_sec), 1, (uint64_t)&buf, fat32_part_info[part_id].ahci_ctrl_num, fat32_part_info[part_id].ahci_port_num);
buf[cluster & (fat_ent_per_sec - 1)] = (buf[cluster & (fat_ent_per_sec - 1)] & 0xf0000000) | (value & 0x0fffffff);
// 向FAT1和FAT2写入数据
ahci_operation.transfer(ATA_CMD_WRITE_DMA_EXT, fat32_part_info[part_id].FAT1_base_sector + (cluster / fat_ent_per_sec), 1, (uint64_t)&buf, fat32_part_info[part_id].ahci_ctrl_num, fat32_part_info[part_id].ahci_port_num);
ahci_operation.transfer(ATA_CMD_WRITE_DMA_EXT, fat32_part_info[part_id].FAT2_base_sector + (cluster / fat_ent_per_sec), 1, (uint64_t)&buf, fat32_part_info[part_id].ahci_ctrl_num, fat32_part_info[part_id].ahci_port_num);
return 0;
}
/**
* @brief 在父目录中寻找指定的目录项
*
* @param part_id 分区id
* @param name 目录项名字
* @param name_len 目录项名字长度
* @param dentry 父目录
* @param flags
* @return struct fat32_Directory_t* 目标目录项
*/
struct fat32_Directory_t *fat32_lookup(uint32_t part_id, char *name, int name_len, struct fat32_Directory_t *dentry, int flags)
{
int errcode = 0;
uint8_t *buf = kmalloc(fat32_part_info[part_id].bytes_per_clus, 0);
memset(buf, 0, fat32_part_info[part_id].bytes_per_clus);
// 计算父目录项的起始簇号
uint32_t cluster = ((dentry->DIR_FstClusHI << 16) | (dentry->DIR_FstClusLO)) & 0x0fffffff;
/*
kdebug("dentry->DIR_FstClusHI=%#010lx", dentry->DIR_FstClusHI);
kdebug("dentry->DIR_FstClusLo=%#010lx", dentry->DIR_FstClusLO);
kdebug("cluster=%#010lx", cluster);
*/
while (true)
{
// 计算父目录项的起始LBA扇区号
uint64_t sector = fat32_part_info[part_id].first_data_sector + (cluster - 2) * fat32_part_info[part_id].bootsector.BPB_SecPerClus;
//kdebug("fat32_part_info[part_id].bootsector.BPB_SecPerClus=%d",fat32_part_info[part_id].bootsector.BPB_SecPerClus);
//kdebug("sector=%d",sector);
// 读取父目录项的起始簇数据
ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, sector, fat32_part_info[part_id].bootsector.BPB_SecPerClus, (uint64_t)buf, 0, 0);
//ahci_operation.transfer(ATA_CMD_READ_DMA_EXT, sector, fat32_part_info[part_id].bootsector.BPB_SecPerClus, (uint64_t)buf, fat32_part_info[part_id].ahci_ctrl_num, fat32_part_info[part_id].ahci_port_num);
struct fat32_Directory_t *tmp_dEntry = (struct fat32_Directory_t *)buf;
// 查找短目录项
for (int i = 0; i < fat32_part_info[part_id].bytes_per_clus; i += 32, ++tmp_dEntry)
{
// 跳过长目录项
if (tmp_dEntry->DIR_Attr == ATTR_LONG_NAME)
continue;
// 跳过无效页表项、空闲页表项
if (tmp_dEntry->DIR_Name[0] == 0xe5 || tmp_dEntry->DIR_Name[0] == 0x00 || tmp_dEntry->DIR_Name[0] == 0x05)
continue;
// 找到长目录项,位于短目录项之前
struct fat32_LongDirectory_t *tmp_ldEntry = (struct fat32_LongDirectory_t *)tmp_dEntry - 1;
int js = 0;
// 遍历每个长目录项
while (tmp_ldEntry->LDIR_Attr == ATTR_LONG_NAME && tmp_ldEntry->LDIR_Ord != 0xe5)
{
// 比较name1
for (int x = 0; x < 5; ++x)
{
if (js > name_len && tmp_ldEntry->LDIR_Name1[x] == 0xffff)
continue;
else if (js > name_len || tmp_ldEntry->LDIR_Name1[x] != (uint16_t)(name[js++])) // 文件名不匹配,检索下一个短目录项
goto continue_cmp_fail;
}
// 比较name2
for (int x = 0; x < 6; ++x)
{
if (js > name_len && tmp_ldEntry->LDIR_Name2[x] == 0xffff)
continue;
else if (js > name_len || tmp_ldEntry->LDIR_Name2[x] != (uint16_t)(name[js++])) // 文件名不匹配,检索下一个短目录项
goto continue_cmp_fail;
}
// 比较name3
for (int x = 0; x < 2; ++x)
{
if (js > name_len && tmp_ldEntry->LDIR_Name3[x] == 0xffff)
continue;
else if (js > name_len || tmp_ldEntry->LDIR_Name3[x] != (uint16_t)(name[js++])) // 文件名不匹配,检索下一个短目录项
goto continue_cmp_fail;
}
if (js >= name_len) // 找到需要的目录项,返回
{
struct fat32_Directory_t *p = (struct fat32_Directory_t *)kmalloc(sizeof(struct fat32_Directory_t), 0);
*p = *tmp_dEntry;
kfree(buf);
return p;
}
--tmp_ldEntry; // 检索下一个长目录项
}
// 不存在长目录项,匹配短目录项的基础名
js = 0;
for (int x = 0; x < 8; ++x)
{
switch (tmp_dEntry->DIR_Name[x])
{
case ' ':
if (!(tmp_dEntry->DIR_Attr & ATTR_DIRECTORY)) // 不是文件夹(是文件)
{
if (name[js] == '.')
continue;
else if (tmp_dEntry->DIR_Name[x] == name[js])
{
++js;
break;
}
else
goto continue_cmp_fail;
}
else // 是文件夹
{
if (js < name_len && tmp_dEntry->DIR_Name[x] == name[js]) // 当前位正确匹配
{
++js;
break; // 进行下一位的匹配
}
else if (js == name_len)
continue;
else
goto continue_cmp_fail;
}
break;
// 当前位是字母
case 'A' ... 'Z':
case 'a' ... 'z':
if (tmp_dEntry->DIR_NTRes & LOWERCASE_BASE) // 为兼容windows系统检测DIR_NTRes字段
{
if (js < name_len && (tmp_dEntry->DIR_Name[x] + 32 == name[js]))
{
++js;
break;
}
else
goto continue_cmp_fail;
}
else
{
if (js < name_len && tmp_dEntry->DIR_Name[x] == name[js])
{
++js;
break;
}
else
goto continue_cmp_fail;
}
break;
case '0' ... '9':
if (js < name_len && tmp_dEntry->DIR_Name[x] == name[js])
{
++js;
break;
}
else
goto continue_cmp_fail;
break;
default:
++js;
break;
}
}
// 若短目录项为文件,则匹配扩展名
if (!(tmp_dEntry->DIR_Attr & ATTR_DIRECTORY))
{
++js;
for (int x = 8; x < 11; ++x)
{
switch (tmp_dEntry->DIR_Name[x])
{
// 当前位是字母
case 'A' ... 'Z':
case 'a' ... 'z':
if (tmp_dEntry->DIR_NTRes & LOWERCASE_EXT) // 为兼容windows系统检测DIR_NTRes字段
{
if ((tmp_dEntry->DIR_Name[x] + 32 == name[js]))
{
++js;
break;
}
else
goto continue_cmp_fail;
}
else
{
if (tmp_dEntry->DIR_Name[x] == name[js])
{
++js;
break;
}
else
goto continue_cmp_fail;
}
break;
case '0' ... '9':
case ' ':
if (tmp_dEntry->DIR_Name[x] == name[js])
{
++js;
break;
}
else
goto continue_cmp_fail;
break;
default:
goto continue_cmp_fail;
break;
}
}
}
struct fat32_Directory_t *p = (struct fat32_Directory_t *)kmalloc(sizeof(struct fat32_Directory_t), 0);
*p = *tmp_dEntry;
kfree(buf);
return p;
continue_cmp_fail:;
}
// 当前簇没有发现目标文件名,寻找下一个簇
cluster = fat32_read_FAT_entry(part_id, cluster);
if (cluster >= 0x0ffffff7) // 寻找完父目录的所有簇,都没有找到目标文件名
{
kfree(buf);
return NULL;
}
}
}
/**
* @brief 按照路径查找文件
*
* @param part_id fat32分区id
* @param path
* @param flags
* @return struct fat32_Directory_t*
*/
struct fat32_Directory_t *fat32_path_walk(uint32_t part_id, char *path, uint64_t flags)
{
// 去除路径前的斜杠
while (*path == '/')
++path;
if ((!*path) || (*path == '\0'))
return NULL;
struct fat32_Directory_t *parent = (struct fat32_Directory_t *)kmalloc(sizeof(struct fat32_Directory_t), 0);
char *dEntry_name = kmalloc(PAGE_4K_SIZE, 0);
memset(parent, 0, sizeof(struct fat32_Directory_t));
memset(dEntry_name, 0, PAGE_4K_SIZE);
parent->DIR_FstClusLO = fat32_part_info[part_id].bootsector.BPB_RootClus & 0xffff;
parent->DIR_FstClusHI = (fat32_part_info[part_id].bootsector.BPB_RootClus >> 16) & 0xffff;
while (true)
{
// 提取出下一级待搜索的目录名或文件名并保存在dEntry_name中
char *tmp_path = path;
while ((*path && *path != '\0') && (*path != '/'))
++path;
int tmp_path_len = path - tmp_path;
memcpy(dEntry_name, tmp_path, tmp_path_len);
dEntry_name[tmp_path_len] = '\0';
//kdebug("dEntry_name=%s", dEntry_name);
struct fat32_Directory_t *next_dir = fat32_lookup(part_id, dEntry_name, tmp_path_len, parent, flags);
if (next_dir == NULL)
{
// 搜索失败
kerror("cannot find the file/dir : %s", dEntry_name);
kfree(dEntry_name);
kfree(parent);
return NULL;
}
while (*path == '/')
++path;
if ((!*path) || (*path == '\0')) // 已经到达末尾
{
if (flags & 1) // 返回父目录
{
kfree(dEntry_name);
kfree(next_dir);
return parent;
}
kfree(dEntry_name);
kfree(parent);
return next_dir;
}
*parent = *next_dir;
kfree(next_dir);
}
}
void fat32_init()
{
spin_init(&fat32_part_reg_lock);
}

View File

@ -13,6 +13,8 @@
#include <filesystem/MBR.h>
#define FAT32_MAX_PARTITION_NUM 128 // 系统支持的最大的fat32分区数量
/**
* @brief fat32文件系统引导扇区结构体
*
@ -56,22 +58,101 @@ struct fat32_BootSector_t
/**
* @brief fat32文件系统的FSInfo扇区结构体
*
*
*/
struct fat32_FSInfo_t
{
uint32_t FSI_LeadSig; // FS info扇区标志符 数值为0x41615252
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; // 空闲簇的起始搜索位置,这是为驱动程序提供的参考值
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
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 读取指定磁盘上的第0个分区的fat32文件系统
*
* @param disk_num
* @brief fat32文件系统短目录项,大小为32bytes
*
*/
void fat32_FS_init(int disk_num);
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));
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 first_data_sector; // 数据区起始扇区号
uint64_t bytes_per_clus; // 每簇字节数
uint64_t FAT1_base_sector; // FAT1表的起始簇号
uint64_t FAT2_base_sector; // FAT2表的起始簇号
};
/**
* @brief 注册指定磁盘上的指定分区的fat32文件系统
*
* @param ahci_ctrl_num ahci控制器编号
* @param ahci_port_num ahci控制器端口编号
* @param part_num 磁盘分区编号
*/
int fat32_register_partition(uint8_t ahci_ctrl_num, uint8_t ahci_port_num, uint8_t part_num);
/**
* @brief 按照路径查找文件
*
* @param part_id fat32分区id
* @param path
* @param flags
* @return struct fat32_Directory_t*
*/
struct fat32_Directory_t *fat32_path_walk(uint32_t part_id, char *path, uint64_t flags);
void fat32_init();