🆕 在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

View File

@ -85,6 +85,9 @@ softirq.o: exception/softirq.c
fat32.o: filesystem/fat32/fat32.c fat32.o: filesystem/fat32/fat32.c
gcc $(CFLAGS) -c filesystem/fat32/fat32.c -o filesystem/fat32/fat32.o gcc $(CFLAGS) -c filesystem/fat32/fat32.c -o filesystem/fat32/fat32.o
MBR.o: filesystem/MBR.c
gcc $(CFLAGS) -c filesystem/MBR.c -o filesystem/MBR.o
# IPI的代码 # IPI的代码
ifeq ($(ARCH), x86_64) ifeq ($(ARCH), x86_64)
OBJ_LIST += ipi.o OBJ_LIST += ipi.o
@ -145,9 +148,9 @@ all: kernel
objcopy -I elf64-x86-64 -O elf64-x86-64 -R ".comment" -R ".eh_frame" kernel ../bin/kernel/kernel.elf objcopy -I elf64-x86-64 -O elf64-x86-64 -R ".comment" -R ".eh_frame" kernel ../bin/kernel/kernel.elf
# #
kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o sched.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o apu_boot.o rtc.o HPET.o softirq.o timer.o fat32.o $(OBJ_LIST) kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o sched.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o apu_boot.o rtc.o HPET.o softirq.o timer.o fat32.o MBR.o $(OBJ_LIST)
ld -b elf64-x86-64 -z muldefs -o kernel head.o exception/entry.o main.o common/printk.o exception/trap.o exception/irq.o mm/mm.o mm/slab.o process/process.o syscall/syscall.o driver/multiboot2/multiboot2.o \ ld -b elf64-x86-64 -z muldefs -o kernel head.o exception/entry.o main.o common/printk.o exception/trap.o exception/irq.o mm/mm.o mm/slab.o process/process.o syscall/syscall.o driver/multiboot2/multiboot2.o \
common/cpu.o smp/smp.o smp/apu_boot.o exception/softirq.o sched/sched.o filesystem/fat32/fat32.o \ common/cpu.o smp/smp.o smp/apu_boot.o exception/softirq.o sched/sched.o filesystem/fat32/fat32.o filesystem/MBR.o \
driver/acpi/acpi.o driver/interrupt/pic.o driver/keyboard/ps2_keyboard.o driver/mouse/ps2_mouse.o driver/disk/ata.o driver/pci/pci.o driver/disk/ahci/ahci.o driver/timers/rtc/rtc.o driver/timers/HPET/HPET.o driver/timers/timer.o \ driver/acpi/acpi.o driver/interrupt/pic.o driver/keyboard/ps2_keyboard.o driver/mouse/ps2_mouse.o driver/disk/ata.o driver/pci/pci.o driver/disk/ahci/ahci.o driver/timers/rtc/rtc.o driver/timers/HPET/HPET.o driver/timers/timer.o \
$(LD_LIST) \ $(LD_LIST) \
-T link.lds -T link.lds

View File

@ -21,7 +21,7 @@
#define ORANGE 0x00ff8000 //橙 #define ORANGE 0x00ff8000 //橙
#define YELLOW 0x00ffff00 //黄 #define YELLOW 0x00ffff00 //黄
#define GREEN 0x0000ff00 //绿 #define GREEN 0x0000ff00 //绿
#define ORANGEBLUE 0x000000ff //蓝 #define BLUE 0x000000ff //蓝
#define INDIGO 0x0000ffff //靛 #define INDIGO 0x0000ffff //靛
#define PURPLE 0x008000ff //紫 #define PURPLE 0x008000ff //紫

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,6 +11,9 @@
#pragma once #pragma once
#include <common/glib.h> #include <common/glib.h>
#define MBR_MAX_AHCI_CTRL_NUM 4 // 系统支持的最大的ahci控制器数量
#define MBR_MAX_AHCI_PORT_NUM 32 // 系统支持的每个ahci控制器对应的MBR磁盘数量对应ahci磁盘号
/** /**
* @brief MBR硬盘分区表项的结构 * @brief MBR硬盘分区表项的结构
* *
@ -42,3 +45,13 @@ struct MBR_disk_partition_table_t
struct MBR_disk_partition_table_entry_t DPTE[4]; // 磁盘分区表项 struct MBR_disk_partition_table_entry_t DPTE[4]; // 磁盘分区表项
uint16_t BS_TrailSig; 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 "fat32.h"
#include <common/kprint.h> #include <common/kprint.h>
#include <driver/disk/ahci/ahci.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 0fat32文件系统 * @brief fat32文件系统
* *
* @param disk_num * @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; for (int i = 0; i <= max_fat32_parts_id; ++i)
unsigned char buf[512]; {
struct MBR_disk_partition_table_t DPT; if (fat32_part_info_bmp[i / 64] & (1 << (i % 64)))
struct fat32_BootSector_t fat32_bootsector; {
struct fat32_FSInfo_t fat32_fsinfo; // 已经注册
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++) // for(i = 0 ;i < 512 ; i++)
// color_printk(PURPLE,WHITE,"%02x",buf[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); 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; fat32_part_info[current_part_id].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].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); 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_part_info[current_part_id].fsinfo = *(struct fat32_FSInfo_t *)buf;
fat32_fsinfo = *(struct fat32_FSInfo_t *)buf;
// for(i = 0 ;i < 512 ; i++) // for(i = 0 ;i < 512 ; i++)
// printk_color(PURPLE,WHITE,"%02x",buf[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> #include <filesystem/MBR.h>
#define FAT32_MAX_PARTITION_NUM 128 // 系统支持的最大的fat32分区数量
/** /**
* @brief fat32文件系统引导扇区结构体 * @brief fat32文件系统引导扇区结构体
* *
@ -69,9 +71,88 @@ struct fat32_FSInfo_t
uint32_t FSI_TrailSig; // 结束标志数值为0xaa550000 uint32_t FSI_TrailSig; // 结束标志数值为0xaa550000
} __attribute__((packed)); } __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 0fat32文件系统 * @brief fat32文件系统短目录项,32bytes
* *
* @param disk_num
*/ */
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();

View File

@ -147,6 +147,7 @@ void system_initialize()
// ata_init(); // ata_init();
pci_init(); pci_init();
ahci_init(); ahci_init();
fat32_init();
// test_slab(); // test_slab();
// test_mm(); // test_mm();
@ -155,7 +156,6 @@ void system_initialize()
current_pcb->preempt_count = 0; current_pcb->preempt_count = 0;
process_init(); process_init();
HPET_init(); HPET_init();
} }
//操作系统内核从这里开始执行 //操作系统内核从这里开始执行
@ -182,10 +182,18 @@ void Start_Kernel(void)
system_initialize(); system_initialize();
int part_id = fat32_register_partition(0, 0, 0);
struct fat32_Directory_t *dentry = fat32_path_walk(part_id, "a.txt", 0);
if (dentry != NULL)
printk_color(BLUE, BLACK, "Find a.txt\nDIR_FstClusHI:%#018lx\tDIR_FstClusLO:%#018lx\tDIR_FileSize:%#018lx\n", dentry->DIR_FstClusHI, dentry->DIR_FstClusLO, dentry->DIR_FileSize);
else
printk_color(BLUE, BLACK, "Can`t find file\n");
fat32_FS_init(0); dentry = fat32_path_walk(part_id, "xx/12.png", 0);
if (dentry != NULL)
printk_color(BLUE, BLACK, "Find xx/12.png\nDIR_FstClusHI:%#018lx\tDIR_FstClusLO:%#018lx\tDIR_FileSize:%#018lx\n", dentry->DIR_FstClusHI, dentry->DIR_FstClusLO, dentry->DIR_FileSize);
else
printk_color(BLUE, BLACK, "Can`t find file\n");
// show_welcome(); // show_welcome();
// test_mm(); // test_mm();

View File

@ -1,4 +1,7 @@
echo "Creating virtual disk image..." echo "Creating virtual disk image..."
qemu-img create -f raw disk.img 16M qemu-img create -f raw disk.img 16M
mkfs.vfat -f 32 disk.img fdisk disk.img
echo "Successfully created disk image, please move it to folder ../bin/" sudo losetup -P /dev/loop1 --show disk.img
lsblk
#mkfs.vfat -F 32 /dev/loop1p1
echo "Successfully created disk image, please make a FAT32 filesystem on it and move it to folder ../bin/"

4
tools/mount_virt_disk.sh Normal file
View File

@ -0,0 +1,4 @@
sudo losetup -P /dev/loop1 --show ../bin/disk.img
lsblk
mkdir -p ../bin/disk_mount/
sudo mount /dev/loop1p1 ../bin/disk_mount/

View File

@ -0,0 +1,3 @@
sudo umount ../bin/disk_mount/
rm -rf ../bin/disk_mount/
sudo losetup -d /dev/loop1