📄 fat32.c
字号:
#include "../include/fs/fat32.h"#define PHY_SECT(n) (n)#define SECTS(n) (n)//获得磁盘簇clus所对应的第一个扇区号#define FIRST_SECT_CLUST(clus) \((clus-2)*super_block.SecPerClus)+first_data_sector#define BUF_LEN 1024extern char sys_dma2_done;struct super_block super_block;FAT32_DIR_ENTRY_SHORT *fat32_dir_entry_short;FAT32_DIR_ENTRY_LONG *fat32_dir_entry_long;unsigned char fs_buf[BUF_LEN] __attribute__ ((aligned(4)));unsigned int root_dir_secs; //根目录占用的扇区数,对FAT32来说为0unsigned int fat_sz; //FAT区域占用的扇区数unsigned int total_sec; //文件系统的总扇区数unsigned int data_sec; //文件系统中存放文件数据的扇区数目unsigned int data_clus; //文件系统中存放文件数据的磁盘簇数目unsigned int first_data_sector; //文件系统中存放文件数据的第一个扇区号unsigned int current_clus; //当前目录的簇号void dump_fs_info(){ printk("BytsPerSec :0x%0x\n",super_block.BytsPerSec); printk("SecPerClus :0x%0x\n",super_block.SecPerClus); printk("RsvdSecCnt :0x%0x\n",super_block.RsvdSecCnt); printk("NumFATs :0x%0x\n",super_block.NumFATs); printk("RootEntCnt :0x%0x\n",super_block.RootEntCnt); printk("TotSec16 :0x%0x\n",super_block.TotSec16); printk("Media :0x%0x\n",super_block.Media); printk("FATSz16 :0x%0x\n",super_block.FATSz16); printk("SecPerTrk :0x%0x\n",super_block.SecPerTrk); printk("NumHeads :0x%0x\n",super_block.NumHeads); printk("HiddSec :0x%0x\n",super_block.HiddSec); printk("TotSec32 :0x%0x\n",super_block.TotSec32); printk("FAT32_FATSz32 :0x%0x\n",super_block.FAT32_FATSz32); printk("FAT32_ExtFlags :0x%0x\n",super_block.FAT32_ExtFlags); printk("FAT32_FSVer :0x%0x\n",super_block.FAT32_FSVer); printk("FAT32_RootClus :0x%0x\n",super_block.FAT32_RootClus); printk("FAT32_FSInfo :0x%0x\n",super_block.FAT32_FSInfo); printk("FAT32_BkBootSec :0x%0x\n",super_block.FAT32_BkBootSec); printk("FAT32_DrvNum :0x%0x\n",super_block.FAT32_DrvNum); printk("FAT32_BootSig :0x%0x\n",super_block.FAT32_BootSig); printk("FAT32_VolID :0x%0x\n",super_block.FAT32_VolID);}/* * 读0号扇区初始化超级块 */void init_super_block(){ sdRead(0,1,fs_buf); *(((char *)&super_block.BytsPerSec)+0) =*((unsigned char *)(fs_buf+BPB_BYTES_PER_SEC)); *(((char *)&super_block.BytsPerSec)+1) =*((unsigned char *)(fs_buf+BPB_BYTES_PER_SEC+1)); super_block.SecPerClus =*((unsigned char *)(fs_buf+BPB_SEC_PER_CLUS)); super_block.RsvdSecCnt =*((unsigned short *)(fs_buf+BPB_RSVD_SEC_CNT)); super_block.NumFATs =*((unsigned char *)(fs_buf+BPB_NUM_FATS)); *(((char *)&super_block.RootEntCnt)+0) =*((unsigned char *)(fs_buf+BPB_ROOT_ENT_CNT)); *(((char *)&super_block.RootEntCnt)+1) =*((unsigned char *)(fs_buf+BPB_ROOT_ENT_CNT+1)); super_block.TotSec16 =*((unsigned short *)(fs_buf+BPB_TOT_SEC16)); super_block.Media =*((unsigned char *)(fs_buf+BPB_MEDIA)); super_block.FATSz16 =*((unsigned short *)(fs_buf+BPB_FATSZ16)); super_block.SecPerTrk =*((unsigned short *)(fs_buf+BPB_SEC_PER_TRK)); super_block.NumHeads =*((unsigned short *)(fs_buf+BPB_NUM_HEADS)); super_block.HiddSec =*((unsigned int *)(fs_buf+BPB_HIDD_SEC)); super_block.TotSec32 =*((unsigned int *)(fs_buf+BPB_TOT_SEC32)); super_block.FAT32_FATSz32 =*((unsigned int *)(fs_buf+BPB_FAT32_FATSZ32)); super_block.FAT32_ExtFlags =*((unsigned short *)(fs_buf+BPB_FAT32_EXT_FLAGS)); super_block.FAT32_FSVer =*((unsigned short *)(fs_buf+BPB_FAT32_FSVER)); super_block.FAT32_RootClus =*((unsigned int *)(fs_buf+BPB_FAT32_ROOT_CLUS)); super_block.FAT32_FSInfo =*((unsigned short *)(fs_buf+BPB_FAT32_FS_INFO)); super_block.FAT32_BkBootSec =*((unsigned short *)(fs_buf+BPB_FAT32_BKBOOT_SEC)); super_block.FAT32_DrvNum =*((unsigned char *)(fs_buf+BS_FAT32_DRV_NUM)); super_block.FAT32_BootSig =*((unsigned char *)(fs_buf+BS_FAT32_BOOT_SIG)); super_block.FAT32_VolID =*((unsigned int *)(fs_buf+BS_FAT32_VOL_ID));}/* * 本函数根据超级块中的数据判断文件系统的类型 * 目前只支持FAT32 */char dete_fat_type(){ /* * root_dir_secs为文件系统根目录所占用的扇区, * FAT32的root_dir_secs为0 */ root_dir_secs =((super_block.RootEntCnt*32)+ (super_block.BytsPerSec-1))/ super_block.BytsPerSec; //获得fat区占用的扇区数 if(super_block.FATSz16!=0) fat_sz=super_block.FATSz16; else fat_sz=super_block.FAT32_FATSz32; //获得文件系统中的扇区总数 if(super_block.TotSec16!=0) total_sec=super_block.TotSec16; else total_sec=super_block.TotSec32; /* * 获得文件系统中存放文件数据的扇区数 * 存放数据的扇区数=总扇区数-保留扇区数-fat扇 * 区数-根目录占用的扇区数 */ data_sec=total_sec-(super_block.RsvdSecCnt+ (super_block.NumFATs*fat_sz)+ root_dir_secs); //获得文件系统中存放文件数据的的磁盘簇数目 data_clus=data_sec/super_block.SecPerClus; //根据data_clus的数目判断本文件系统的类型 if(data_clus<4085) { return FAT12; } else if(data_clus<65525) { return FAT16; } else { return FAT32; } }/*void ShowDate(unsigned short date){ printk("%d-",((date>>9)&0x7f)+1980); printk("%d-",(date>>5)&0xf); printk("%d",date&0x1f); }void ShowTime(unsigned short time){ printk("%d:",((time>>11)&0x1f)); printk("%d:",(time&0x1f)*2); printk("%d",(time>>5)&0x3f);}void ShowShortName(unsigned char *buf){ int i; for(i=0;i<11;i++) printk("%c",buf[i]);}void ShowLongName(FAT32_DIR_ENTRY_LONG *long_entry){ printk("%s",fat32_dir_entry_long->LDIR_Name1); printk("%s",fat32_dir_entry_long->LDIR_Name2); printk("%s",fat32_dir_entry_long->LDIR_Name3);}unsigned int get_root_dir(){ unsigned int next_clus=super_block.FAT32_RootClus; int j; int k; int entry; int long_entry_counter; do { sdRead(FIRST_SECT_CLUST(next_clus),2,(unsigned char *)fs_buf); entry=0; long_entry_counter=0; while(entry<1024/32) { fat32_dir_entry_short=(FAT32_DIR_ENTRY_SHORT *)fs_buf+entry; //是一个long entry if(fat32_dir_entry_short->Dir_Attr==ATTR_LONG_NAME) { entry++; long_entry_counter++; continue; } else//是一个short entry { if(fat32_dir_entry_short->Dir_Name[0]==0xe5) { entry++; long_entry_counter=0; continue; } if(fat32_dir_entry_short->Dir_Name[0]==0x00) { long_entry_counter=0; break; } //directory entry完全有short entry组成 if(long_entry_counter==0) { ShowShortName(fat32_dir_entry_short->Dir_Name); printk(" "); } else//directory entry由short entry和long entry组成 { for(k=1;k<=long_entry_counter;k++) { fat32_dir_entry_long=(FAT32_DIR_ENTRY_LONG *)fat32_dir_entry_short-k; ShowLongName(fat32_dir_entry_long); } printk(" "); } ShowDate(fat32_dir_entry_short->DIR_CrtDate); printk(" "); ShowTime(fat32_dir_entry_short->DIR_CrtTime); printk(" "); printk("0x%0x",fat32_dir_entry_short->Dir_Attr); printk("\n"); entry++; long_entry_counter=0; } } }while((next_clus=FAT32_entry(next_clus))&0x0fffffff!=0x0fffffff); printk("show root done.\n"); return 1;}*//* * 根据磁盘簇号获得该磁盘簇对应的FAT条目 */unsigned int get_fat_entry(unsigned int cluster_num){ unsigned int FAT32_SECTNUM=super_block.RsvdSecCnt+ ((cluster_num*4)/super_block.BytsPerSec); unsigned int FAT32_ENT_OFFSET=(cluster_num*4)%super_block.BytsPerSec; unsigned int fat32_entry; sdRead(FAT32_SECTNUM,1,&fs_buf); fat32_entry=(*((unsigned int *)fs_buf[FAT32_ENT_OFFSET]))&0x0FFFFFFF; return fat32_entry;}//获得根目录的簇号unsigned int get_root_clus(){ return super_block.FAT32_RootClus;}/* * 获得第一个存放文件数据的扇区号 */unsigned int get_first_data_sec(){ unsigned int sec=super_block.RsvdSecCnt+ (super_block.NumFATs * super_block.FAT32_FATSz32) + root_dir_secs; return sec;}int mount_fat32(){ //初始化super_block init_super_block(); //打印超级块信息 //dump_fs_info(); if(dete_fat_type()!=FAT32) { return -1; } //系统启动的时候当前磁盘簇为根目录磁盘簇 current_clus=get_root_clus(); //获得文件系统中第一个存放文件数据的扇区号 first_data_sector=get_first_data_sec(); //get_root_dir(); return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -