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

📄 apfs_fat32_base.c

📁 一个可以在开发板上运行的fat文件系统,是在windows平台下开发的,是学习文件系统的好帮手
💻 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 + -