⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.c

📁 基于s3c2410、2440的从SD卡引导Linux内核程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "Fat.h"
#include "UART.h"
#include "SD.h"
#include <stdlib.h>

#define debug				0
#define List_DirFile_EN		1

unsigned char	BUFFER[512] = {0};

//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
volatile struct
{
	unsigned int unknown:	1;
	unsigned int isFat16:	1;
	unsigned int isFat32:	1;
	unsigned int isDir:		1;	//当前目录下指定的是目录
	unsigned int isFile:	1;	//当前目录下指定的是文件
}Flags;

unsigned short	BytesPerSector=0;		//每扇区字节数
unsigned char	SectorsPerCluster=0;	//每簇扇区数

unsigned int	StartSector=0;			//分区起始扇区地址,即DBR_LBA
unsigned int	FATSector=0;			//文件分配表(FAT)起始扇区地址
unsigned int	RootDirCluster=0;		//根目录所在簇号
unsigned int	RootDirSector=0;		//根目录起始扇区地址
unsigned int	DataSector=0;			//数据区起始扇区地址

unsigned int	TotalSectors=0;			//分区总容量
unsigned int	FAT_Size=0;				//文件分配表(FAT)大小
unsigned int	RootDir_Size=0;			//根目录大小,Fat32时为0
unsigned int	Data_Size=0;			//数据区大小

#define	ClusterToSector(N)	((N - 2) * SectorsPerCluster + DataSector)	//簇号 -> 扇区号

unsigned int	DirCluster=0;			//当前目录所在簇号,用于表识当前活动的目录
unsigned int	DirFileCluster=0;		//当前目录下指定的文件或子目录所在簇号,用于表识即将打开的文件或子目录
unsigned int	DirFile_Size=0;			//当前目录下指定的文件或子目录的大小

//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
//初始化文件系统信息
//-----------------------------------------------------------------------
int Fat_Init(void)
{
	DBR *dbr;
	BPB *bpb;
	DPT *PartInfo;
	
#if debug	
	unsigned int i;
#endif

	Uart_Printf(0,"Now,Start to Init FileSystem.\n");

	// 读MBR结构
	ReadS(0,(unsigned int *)BUFFER,512);
	
#if debug
	Uart_Printf(0,"MBR is \n");
	for(i=0;i<32;i++)
		Uart_Printf(0,"0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n",BUFFER[0+i*16],BUFFER[1+i*16],BUFFER[2+i*16],BUFFER[3+i*16],BUFFER[4+i*16],BUFFER[5+i*16],BUFFER[6+i*16],BUFFER[7+i*16],BUFFER[8+i*16],BUFFER[9+i*16],BUFFER[10+i*16],BUFFER[11+i*16],BUFFER[12+i*16],BUFFER[13+i*16],BUFFER[14+i*16],BUFFER[15+i*16]);
#endif

	// 读取第0分区表信息,并分析
	PartInfo = ((DPT *)(((MBR *)BUFFER)->psPart + 16 * 0));	//指向第0分区表项
	switch (PartInfo->prPartType)//查询该分区文件系统类型
	{
		case PART_TYPE_FAT12:
		case PART_TYPE_DOSFAT16:
		case PART_TYPE_FAT16: 
		case PART_TYPE_FAT16LBA:
			Flags.isFat16 = 1;	//该分区为Fat16
			Flags.isFat32 = 0;
			Flags.unknown = 0;
			break;

		case PART_TYPE_FAT32LBA:
		case PART_TYPE_FAT32:
			Flags.isFat16 = 0;
			Flags.isFat32 = 1;	//该分区为Fat32
			Flags.unknown = 0;
			break;

		case PART_TYPE_UNKNOWN:
		default:
			Flags.isFat16 = 0;
			Flags.isFat32 = 0;
			Flags.unknown = 1;	//无法识别该分区
			break;
	}
	
	//TotalSectors = PartInfo->prSize;		//分区容量
	StartSector = PartInfo->prStartLBA;		//分区起始扇区地址

	// 读分区引导扇区
	// 引导扇区号在PartInfo.prStartLBA中
	ReadS(StartSector,(unsigned int *)BUFFER,512);
	
#if debug
	Uart_Printf(0,"StartSector is \n");
	for(i=0;i<32;i++)
		Uart_Printf(0,"0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n",BUFFER[0+i*16],BUFFER[1+i*16],BUFFER[2+i*16],BUFFER[3+i*16],BUFFER[4+i*16],BUFFER[5+i*16],BUFFER[6+i*16],BUFFER[7+i*16],BUFFER[8+i*16],BUFFER[9+i*16],BUFFER[10+i*16],BUFFER[11+i*16],BUFFER[12+i*16],BUFFER[13+i*16],BUFFER[14+i*16],BUFFER[15+i*16]);
#endif	

	dbr = (DBR *) BUFFER;		//调整指针 
	bpb = (BPB *) dbr->bsBPB;	//调整指针

	BytesPerSector		= bpb->bpbBytesPerSec;					//每扇区字节数
	SectorsPerCluster	= bpb->bpbSecPerClust;					//每簇扇区数
	FATSector			= bpb->bpbResSectors + StartSector;		//文件分配表(FAT)起始扇区地址
	
	if(Flags.isFat16)
	{
		TotalSectors	= bpb->bpbSmallSectors;					//分区容量
		FAT_Size		= bpb->bpbFATs * bpb->bpbFATsecs;		//文件分配表(FAT)大小
		RootDirCluster	= 1;									//根目录簇号
	}
	if(Flags.isFat32)
	{
		TotalSectors	= bpb->bpbHugeSectors;					//分区容量
		FAT_Size		= bpb->bpbFATs * bpb->bpbBigFATsecs;	//文件分配表(FAT)大小
		RootDirCluster	= bpb->bpbRootClust;					//根目录簇号
	}
	
	DirCluster		= RootDirCluster;															//初始当前活动目录为根目录
	RootDir_Size	= ((bpb->bpbRootDirEnts * 32) + (BytesPerSector - 1)) / BytesPerSector;		//根目录大小
	RootDirSector	= FATSector + FAT_Size;														//根目录起始扇区地址
	Data_Size		= TotalSectors - (bpb->bpbResSectors + FAT_Size + RootDir_Size);			//数据区大小
	DataSector		= RootDirSector + RootDir_Size;												//数据区起始扇区地址

#if debug
	if(Flags.isFat16) Uart_Printf(0,"It is Fat16.\n");
	if(Flags.isFat32) Uart_Printf(0,"It is Fat32.\n");

	Uart_Printf(0,"TotalSectors = %d\n",TotalSectors);

	Uart_Printf(0,"StartSector = %d\n",StartSector);

	Uart_Printf(0,"BytesPerSector =  %d\n",BytesPerSector);

	Uart_Printf(0,"SectorsPerCluster = %d\n",SectorsPerCluster);

	Uart_Printf(0,"FATSector = %d\n",FATSector);

	Uart_Printf(0,"FAT_Size = %d\n",FAT_Size);

	Uart_Printf(0,"RootDirCluster = %d\n",RootDirCluster);
	
	Uart_Printf(0,"RootDirSector = %d\n",RootDirSector);

	Uart_Printf(0,"RootDir_Size = %d\n",RootDir_Size);

	Uart_Printf(0,"DataSector = %d\n",DataSector);

	Uart_Printf(0,"Data_Size = %d\n",Data_Size);

//厂商标志和OS版本号
	Uart_Printf(0,"The OEMName is %s\n",dbr->bsOEMName);
//显示磁盘容量
	Uart_Printf(0,"The SDCard'Size is %d Bits\n",TotalSectors<<9);
	Uart_Printf(0,"############################################\n");
#endif

	return 1;	
}
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
//在FAT表中查询下一个簇所在扇区号
//-----------------------------------------------------------------------
unsigned int FatNextCluster(unsigned int cluster)
{
	unsigned int nextCluster;
	unsigned int fatMask;
	unsigned int fatOffset;
	unsigned int sector;
	unsigned int offset;
	
#if debug
	unsigned int i;
#endif
	
	if(Flags.isFat16)
	{
		// 一个表项为2bytes(16 bits)
		fatOffset = cluster << 1;
		// 设置 FAT16 bit mask
		fatMask = FAT16_MASK;
	}
	if(Flags.isFat32)
	{
		// 一个表项为4bytes(32 bits)
		fatOffset = cluster << 2;
		// 设置 FAT32 bit mask
		fatMask = FAT32_MASK;
	}
	
	//计算FAT扇区号
	sector = FATSector + (fatOffset / BytesPerSector);
	//计算FAT扇区号中表项的偏移地址
	offset = fatOffset % BytesPerSector;
	
#if debug
	Uart_Printf(0,"The Cluster Sector is %d\n",sector);
	Uart_Printf(0,"The Cluster Offset is %d\n",offset);
#endif

	ReadS(sector,(unsigned int *)BUFFER,512);
	
#if debug
	Uart_Printf(0,"Cluster is \n");
	for(i=0;i<32;i++)
		Uart_Printf(0,"0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n",BUFFER[0+i*16],BUFFER[1+i*16],BUFFER[2+i*16],BUFFER[3+i*16],BUFFER[4+i*16],BUFFER[5+i*16],BUFFER[6+i*16],BUFFER[7+i*16],BUFFER[8+i*16],BUFFER[9+i*16],BUFFER[10+i*16],BUFFER[11+i*16],BUFFER[12+i*16],BUFFER[13+i*16],BUFFER[14+i*16],BUFFER[15+i*16]);
#endif
	
	// 读取下一个簇号
	if(Flags.isFat16)
	{
		//nextCluster = (*((unsigned int*) &((char*)BUFFER)[offset])) & fatMask;
		nextCluster = (unsigned int)(*(unsigned short*)&(((FAT *)BUFFER)->Item[offset])) & fatMask;
	}
	if(Flags.isFat32)
	{
		//nextCluster = (*((unsigned int*) &((char*)BUFFER)[offset])) & fatMask;
		nextCluster = *(unsigned int*)&(((FAT *)BUFFER)->Item[offset]) & fatMask;
	}

	// 是否文件的结束簇
	if (nextCluster == (CLUST_EOFE & fatMask))
		nextCluster = 0;

#if debug
	Uart_Printf(0,"The Current Cluster is %d\n",cluster);
	Uart_Printf(0,"The Next Cluster is %d\n",nextCluster);
	Uart_Printf(0,"############################################\n");
#endif

	return nextCluster;
}
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
//
//-----------------------------------------------------------------------
#if List_DirFile_EN
void List_DirFile(void)
{
	unsigned char i,j,k;
	unsigned int kk;
	DirFile	*dirfile;

	kk = DirCluster;	//当前目录所在簇号

	while(1)
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -