📄 apfs_fat32_base.c
字号:
//-----------------------------------------------------------------------------
// This file is part of AP.FS
// AP.FS is a FAT32 file system face to the embedded system,It's target is to
// support the portable storage device such as SD Card,TF Card or USB Disc 's
// file system.
// please login www.another-prj.com to get more details.
// caiyuqing
// 2008-1-8
//-----------------------------------------------------------------------------
#include "apfs_fat32_definitions.h"
#include "apfs_fat32_access.h"
#include "apfs_fat32_base.h"
// fat32_struct is a global symbol
struct fat32 fat32_struct;
//-----------------------------------------------------------------------------
// apfs_fat32_find_lba_begin: This function is used to find the LBA Address of
// the first volume on the disc. Also checks are performed on the signature and
// identity codes to make sure the partition is FAT32.
//-----------------------------------------------------------------------------
BOOL apfs_fat32_find_lba_begin(BYTE *buffer, UINT32 *lba_begin)
{
if(buffer == NULL)
{
return FALSE;
}
// Load MBR (LBA 0) into the 512 byte buffer
if(!apfs_fat32_read_sector(0, buffer))
{
return FALSE;
}
// Make Sure 0x55 and 0xAA are at end of sector
if(GET_16BIT_WORD(buffer, SIGNATURE_POSITION) != SIGNATURE_VALUE)
{
return FALSE;
}
// TODO: Verify this
switch(buffer[PARTITION1_TYPECODE_LOCATION])
{
case 0x0B:
break;
case 0x06:
break;
case 0x0C:
break;
case 0x0E:
break;
case 0x0F:
break;
case 0x05:
break;
default:
if(buffer[PARTITION1_TYPECODE_LOCATION] > 0x06)
{
return FALSE;
}
break;
}
// Read LBA Begin for FAT32 File system is located for partition
// for logic partition,the first lba is located on the first sector.
*lba_begin = GET_32BIT_WORD(buffer, PARTITION1_LBA_BEGIN_LOCATION);
//*lbaBegin = 0;
// Return the LBA address of FAT table
return TRUE;
}
//-----------------------------------------------------------------------------
// apfs_fat32_init: Uses apfs_fat32_find_lba_begin to find the lba for the volume,
// and loads into memory some specific details of the partitionw which are used
// in further calculations.
//-----------------------------------------------------------------------------
BOOL apfs_fat32_init(void)
{
BYTE buffer[512];
BYTE number_of_FATS;
UINT16 reserved_sectors;
UINT32 lba_begin;
UINT32 FATSz;
UINT32 root_dir_sectors;
UINT32 total_sec;
UINT32 data_sec;
UINT32 count_of_clusters;
apfs_init_fats_internal();
apfs_fat32_init_sector_buffer();
apfs_fat32_init_lib();
// Check Volume 1 and find LBA address
if(apfs_fat32_find_lba_begin(buffer, &lba_begin))
{
fat32_struct.cluster_begin_lba = lba_begin;
// Load Volume 1 table into sector buffer
if(!apfs_fat32_read_sector(lba_begin, buffer))
{
return FALSE;
}
// Make sure there are 512 bytes per cluster
if(GET_16BIT_WORD(buffer, 0x0B)!=0x200)
{
return FALSE;
}
// Load Parameters of FAT32
fat32_struct.sectors_per_cluster = buffer[BPB_SecPerClus];
reserved_sectors = GET_16BIT_WORD(buffer, BPB_RsvdSecCnt);
number_of_FATS = buffer[BPB_NumFATs];
fat32_struct.fat_sectors = GET_32BIT_WORD(buffer, BPB_FAT32_FATSz32);
fat32_struct.rootdir_first_cluster = GET_32BIT_WORD(buffer, BPB_FAT32_RootClus);
fat32_struct.fs_info_sector = GET_16BIT_WORD(buffer, BPB_FAT32_FSInfo);
// First FAT LBA address
fat32_struct.fat_begin_lba = lba_begin + reserved_sectors;
// The address of the first data cluster on this volume
fat32_struct.cluster_begin_lba = fat32_struct.fat_begin_lba +
(number_of_FATS * fat32_struct.fat_sectors);
// This signature should be AA55
if (GET_16BIT_WORD(buffer, 0x1FE) != 0xAA55)
{
return FALSE;
}
// Calculate the root dir sectors
root_dir_sectors = ((GET_16BIT_WORD(buffer, BPB_RootEntCnt) * 32) +
(GET_16BIT_WORD(buffer, BPB_BytsPerSec) - 1)) /
GET_16BIT_WORD(buffer, BPB_BytsPerSec);
if(GET_16BIT_WORD(buffer, BPB_FATSz16) != 0)
{
FATSz = GET_16BIT_WORD(buffer, BPB_FATSz16);
}
else
{
FATSz = GET_32BIT_WORD(buffer, BPB_FAT32_FATSz32);
}
if(GET_16BIT_WORD(buffer, BPB_TotSec16) != 0)
{
total_sec = GET_16BIT_WORD(buffer, BPB_TotSec16);
}
else
{
total_sec = GET_32BIT_WORD(buffer, BPB_TotSec32);
}
data_sec = total_sec - (GET_16BIT_WORD(buffer, BPB_RsvdSecCnt) +
(buffer[BPB_NumFATs] * FATSz) + root_dir_sectors);
count_of_clusters = data_sec / fat32_struct.sectors_per_cluster;
//check the FAT type
if(count_of_clusters < 4085)
{
// Volume is FAT12
return FALSE;
}
else if(count_of_clusters < 65525)
{
// Volume is FAT16
return FALSE;
}
// Volume is FAT32
return TRUE;
}
else
{
return FALSE;
}
}
//-----------------------------------------------------------------------------
// apfs_fat32_lba_of_cluster: This function converts a cluster number into a
// sector lba number.
//-----------------------------------------------------------------------------
UINT32 apfs_fat32_lba_of_cluster(UINT32 cluster_number)
{
return ((fat32_struct.cluster_begin_lba +
((cluster_number - 2) * fat32_struct.sectors_per_cluster)));
}
//-----------------------------------------------------------------------------
// apfs_fat32_init: Uses apfs_fat32_find_lba_begin to find the LBA for the volume,
// and loads into memory some specific details of the partitionw which are used
// in further calculations.
//-----------------------------------------------------------------------------
void apfs_fat32_show_details(struct fat32 *fat32_struct)
{
printk("sectors_per_cluster %d\n", fat32_struct->sectors_per_cluster);
printk("cluster_begin_lba %d\n", fat32_struct->cluster_begin_lba);
printk("rootdir_first_cluster %d\n", fat32_struct->rootdir_first_cluster);
printk("fat_begin_lba %d\n", fat32_struct->fat_begin_lba);
printk("filenumber %d\n", fat32_struct->filenumber);
printk("fs_info_sector %d\n", fat32_struct->fs_info_sector);
printk("lba_begin %d\n", fat32_struct->lba_begin);
printk("fat_sectors %d\n", fat32_struct->fat_sectors);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -