📄 fat.c
字号:
#include <windows.h>
#include "loader.h"
#include "fat.h"
//#include "ethdown.h"
#include <nkintr.h>
#include <bulverde.h>
#include <bsp.h>
#define FLASH_BIN_START (BOOT_FLASH_BASE_U_VIRTUAL+0x00080000)
#define PrintMsg RETAILMSG
#define MAX_ATA_DEV 1
#define NUM_FILES 1
#define UPCASE(x) ((x) >= 'A' && (x) <= 'Z' ? (x) | 0x20 : (x))
#define MAX_SECTOR_SIZE 512//1024
#define MAX_FAT_SIZE (0xFF*MAX_SECTOR_SIZE)
#define NoError 0
#define FatNumError 1
#define SectorPerClusterOff 0xd
#define J3 1
#ifdef MMXIP_MEMMAP
#define RAM_IMAGE_START 0x96CB8000
#else
#define RAM_IMAGE_START 0x800B8000
#endif
extern void SDPowerOff(void);
extern BOOL SetSDHW(void);
extern ULONG CFATAReadSectors(ULONG Sector,ULONG Count,PUCHAR SectorBuf,ULONG PAtoLA);
extern void Launch(unsigned int uAddr);
int flashType =J3;
struct _FileTable{
BOOLEAN Opened;
ATA_DEVICE *Disk;
DIRENTRY DirEntry;
ULONG Position;
ULONG Cluster;
UCHAR SecBuf[MAX_SECTOR_SIZE];
} FileTable[NUM_FILES];
#pragma pack(1)
typedef struct _BINFILE_HEADER {
UCHAR SyncBytes[7];
ULONG ImageAddress;
ULONG ImageLength;
} BINFILE_HEADER, *PBINFILE_HEADER;
#pragma pack(1)
typedef struct _BINFILE_RECORD_HEADER {
ULONG LoadAddress;
ULONG Length;
ULONG CheckSum;
} BINFILE_RECORD_HEADER, *PBINFILE_RECORD_HEADER;
UINT32 FatLen;
UINT32 DirSector;
BYTE SectorBuf[512*30];
UINT32 PAtoLA = 0;
ULONG FirstFatSector = 0;
ULONG SecondFatSector = 0;
ATA_DEVICE AtaDisks[MAX_ATA_DEV];
BYTE * ImageBufStart = (BYTE*)0x80100000;
void DumpASector(BYTE* Sector)
{
BYTE *pDat;
UINT i;
pDat = Sector;
for(i=0;i<512;i++)
{
if(!(i%16))
EdbgOutputDebugString ("\r\n%X: ",i);
if(*pDat<0x10)
EdbgOutputDebugString ("0%x ",*pDat++);
else
EdbgOutputDebugString ("%x ",*pDat++);
}
EdbgOutputDebugString("\r\n");
}
UINT ATADeviceInit()
{
BOOTSECT *BootSect;
UINT8 FatCount = 0;
ULONG sector = 0;
ATA_DEVICE *Disk = AtaDisks;
CFATAReadSectors(sector,1,SectorBuf,0);
if(*SectorBuf == 0xEB || *(SectorBuf+0x1BE) == 0x80)//这是一个活动分区
PAtoLA = 0;
else
PAtoLA = *(SectorBuf+0x1C6);//相对扇区数,物理地址转逻辑地址
CFATAReadSectors(sector,1,SectorBuf,PAtoLA);
BootSect = (BOOTSECT *)SectorBuf;
Disk->BytesPerSec = (BootSect->BytesPerSec[1] << 8) + BootSect->BytesPerSec[0];//每扇区字节数
Disk->SecPerCluster = BootSect->SecPerAlloc;//每簇扇区数
Disk->SecPerFAT = (USHORT)BootSect->SectorsPerFAT;//每fat扇区数
Disk->NumFATs = BootSect->NumFATs;//fat副本
Disk->ResvSectors = BootSect->ResvSectors;
FirstFatSector = 1;
SecondFatSector = FirstFatSector+Disk->SecPerFAT;
DirSector = SecondFatSector+Disk->SecPerFAT;
EdbgOutputDebugString ("Disk->BytesPerSec :%d\r\n",Disk->BytesPerSec);
EdbgOutputDebugString ("Disk->SecPerCluster :%d\r\n",Disk->SecPerCluster);
EdbgOutputDebugString ("Disk->SecPerFAT :%d\r\n",Disk->SecPerFAT);
EdbgOutputDebugString ("Disk->ResvSectors :%d\r\n",Disk->ResvSectors);
EdbgOutputDebugString ("DirSector :%d\r\n",DirSector);
return(NoError);
}
ULONG FATExtractName(IN PUCHAR Pathname, IN PUCHAR Filename)
{
ULONG i;
ULONG FLen;
ULONG ExLen;
ULONG FirstSlash = 0;
EdbgOutputDebugString ("FATExtractName: Entry.\r\n");
if(Pathname[0] == '\\')
{
Pathname += 1;
FirstSlash = 1;
}
FLen = 8;
for(i = 0; i < 8; i++)
{
if((*Pathname != 0) && (*Pathname != '.') && (*Pathname != '\\'))
Filename[i] = *Pathname++;
else
{
Filename[i] = ' ';
if (FLen == 8)
FLen = i;
}
}
if(*Pathname == '.')
Pathname += 1;
ExLen = 3;
for(i = 0; i < 3; i++)
{
if((*Pathname != 0)&& (*Pathname != '\\'))
Filename[i+8] = *Pathname++;
else
{
Filename[i+8]= ' ';
if (ExLen == 3)
ExLen= i;
}
}
EdbgOutputDebugString ("FATExtractName: Exit.\r\n");
return(FLen + ExLen + FirstSlash);
}
void FATFileClose(IN ULONG FileDesc)
{
EdbgOutputDebugString ("FATFileClose: Entry.\r\n");
//PrintMsg(1, (TEXT("FATFileClose: Entry.\r\n")));
FileDesc -= 1;
if((FileDesc < NUM_FILES) && (FileTable[FileDesc].Opened))
{
FileTable[FileDesc].Opened = FALSE;
}
// PrintMsg(1, (TEXT("FATFileClose: Exit.\r\n")));
EdbgOutputDebugString ("FATFileClose: Exit.\r\n");
}
ULONG FATFileOpen(IN PUCHAR Filename)
{
struct _FileTable *CurFile;
DIRENTRY *CurEntry;
UCHAR FName[13];
ULONG Entries = 512; //目录区目录项的个数,一般为512
UINT32 Sector = DirSector;
UINT32 count=0;
BOOLEAN Match;
BOOLEAN SubDir=0;
int i;
PUCHAR filename = Filename;
// EdbgOutputDebugString ("SectorPerCluster :0x%x\r\n",AtaDisks[0].SecPerCluster);
Filename += FATExtractName(Filename, FName);
if(SubDir = (Filename[0] == '\\'))
{
Filename += 1;
}
for(CurFile = &FileTable[0]; CurFile < &FileTable[NUM_FILES]; CurFile++)
{
if (!CurFile->Opened)
break;
}
if (CurFile == &FileTable[NUM_FILES])
return(0);
while(count<32)
{
CFATAReadSectors(Sector,1,SectorBuf,PAtoLA);
//if(count == 0)
// DumpASector(SectorBuf);
CurEntry = (DIRENTRY *)SectorBuf; //这里全部转换为文件项类型,且指向第一个
while (CurEntry < (DIRENTRY *)&SectorBuf[512])
{
if (CurEntry->FileName[0] != DIRENT_UNUSED && CurEntry->FileName[0] != DIRENT_DELETED)//要确定是可用的项数
{
if (CurEntry->FileName[0] == DIRENT_E5CHAR)
{
CurEntry->FileName[0] = 0xe5;
}
Match = TRUE;
for (i = 0; i < 11 && Match == TRUE; i++)//这里比较文件名
{
Match &= UPCASE(CurEntry->FileName[i]) == UPCASE(FName[i]);
}
if (Match)
{
EdbgOutputDebugString ("FATFileOpen: Found '%s'\r\n",filename);
if (SubDir)
{
EdbgOutputDebugString ("break.\r\n");
break;
}
memcpy(&(CurFile->DirEntry), CurEntry, sizeof(DIRENTRY));//这里匹配到了
CurFile->Cluster = CurEntry->StartCluster;//该文件的起始簇
CurFile->Position = 0;
CurFile->Opened = TRUE;
EdbgOutputDebugString ("FATFileOpen: Exit(1)\r\n");
return((CurFile - FileTable) + 1);
}
}
CurEntry += 1;
Entries -= 1;
if (SubDir && (CurEntry->Attribute & FATTR_DIR));//这里是要查找子目录下的文件
/* {
Sector = DirSector;
Sector += ((512 * sizeof(DIRENTRY)) / 512);
Sector += ((CurEntry->StartCluster-2) * 4);
Filename += FATExtractName(Filename, FName);
if (SubDir = (Filename[0] == '\\'))
{
Filename += 1;
}
Entries = (4 * 512) / sizeof(DIRENTRY);
} */
else
{
// Sector += 1;
// count--;
}
}
Sector += 1;
count++;
}
EdbgOutputDebugString ("Not Found '%s'.\r\n",filename);
return(0);
}
ULONG FATFileSize(IN ULONG FileDesc)
{
// EdbgOutputDebugString ("FATFileSize: Entry.\r\n");
FileDesc -= 1;
if((FileDesc >= NUM_FILES) || (!FileTable[FileDesc].Opened))
{
EdbgOutputDebugString ("FATFileSize: Exit(1).\r\n");
return(0);
}
// EdbgOutputDebugString ("FATFileSize: Exit(2).\r\n");
return(FileTable[FileDesc].DirEntry.Length);
}
ULONG FATGetNextCluster(IN OUT ATA_DEVICE *Disk,
IN ULONG Cluster)
{
ULONG Sector;
PUCHAR FatPtr;
USHORT FatEntry;
ULONG FatOffs;
ULONG BadSector,ErrorMalloc;
BYTE* databuf = SectorBuf;
// EdbgOutputDebugString ("FATGetNextCluster: Entry.\r\n");
BadSector = FAT16_CLUSTER_BAD;
ErrorMalloc = BadSector;
if(Cluster == 0xFFFF)
EdbgOutputDebugString ("File is over\r\n");
if(Cluster >= FAT16_CLUSTER_MAX)
{
EdbgOutputDebugString ("Cluster >= FAT16_CLUSTER_MAX\r\n");
return(BadSector);
}
if(1)
{
Sector = FirstFatSector+(Cluster*2/512);
// databuf = (BYTE*)malloc(Disk->SecPerFAT*sizeof(BYTE));
// if(databuf == NULL)
// return(ErrorMalloc);
// if (CFATAReadSectors(Sector,Disk->SecPerFAT,databuf,PAtoLA)!=0)
if (CFATAReadSectors(Sector,1, databuf,PAtoLA) != 0)
{
PrintMsg(1, (TEXT("FATGetNextCluster : CFATAReadSectors Error!!\r\n")));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -