Files
zTC1/mico-os/platform/MCU/MX1101/FileSystem/partition.c
2025-03-11 15:54:45 +08:00

287 lines
7.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/////////////////////////////////////////////////////////////////////////
// Mountain View Silicon Tech. Inc.
// Copyright 2012, Mountain View Silicon Tech. Inc.,ShangHai,China
// All rights reserved
// Filename:partition.c
/////////////////////////////////////////////////////////////////////////
//#include "app_config.h"
#include "fs_config.h"
#include "folder.h"
#include "fat_file.h"
#include "fsinfo.h"
#include "diskio.h"
#include "presearch.h"
#include "host_stor.h"
#include "Debug.h"
#define SIGNATURE_OFFSET 0x01fe // will contain 0x55AA
#define PARTITION_OFFSET 0x01be // will contain partition table
#define COMMON_SIGNATURE 0xAA55
#define FS_DBG(M, ...)
//define partition structure
#pragma pack(1)
typedef struct _PARTITION // Partition Entries definition
{
uint8_t Active;
uint8_t StartHead;
uint8_t StartSector;
uint8_t StartCylinder;
uint8_t PartitionType;
uint8_t EndHead;
uint8_t EndSector;
uint8_t EndCylinder;
uint32_t FirstSectorNum;
uint32_t SectorCount;
} PARTITION;
#pragma pack()
//define BPB structe
#pragma pack(1)
typedef struct
{
uint8_t BS_jmpBoot[3]; // 0-2
uint8_t BS_OEMName[8]; // 3-10
uint16_t BPB_BytsPerSec; // 11-12
uint8_t BPB_SecPerClus; // 13
uint16_t BPB_RsvdSecCnt; // 14-15
uint8_t BPB_NumFATs; // 16
uint16_t BPB_RootEntCnt; // 17-18
uint16_t BPB_TotSec16; // 19-20
uint8_t BPB_Media; // 21
uint16_t BPB_FATSz16; // 22-23
uint16_t BPB_SecPerTrk; // 24-25
uint16_t BPB_NumHeads; // 26-27
uint32_t BPB_HiddSec; // 28-31
uint32_t BPB_TotSec32; // 32-35
uint32_t BPB_FATSz32; // 36-39
uint16_t BPB_ExtFlags; // 40-41
uint16_t BPB_FSVer; // 42-43
uint32_t BPB_RootClus; // 44-47
uint16_t BPB_FSInfo; // 48-49
uint16_t BPB_BkBootSec; // 50-51
} BOOT_SECTOR;
#pragma pack()
#define CANCEL_COMMON_SIGNATURE_JUDGMENT
// Load partition information from storage device.
bool PartitionLoad(FS_CONTEXT* FsContext, uint8_t DriverId)
{
uint32_t RootDirSectors;
uint32_t BootSecNum = 0;
uint32_t FatSize;
uint32_t TotalSectors;
uint8_t IndexPtb;
uint8_t SectorSizeMul;
uint32_t temp2;
uint8_t ExtBootEntry = 0;
uint16_t BPBRsvSectCnt;
uint8_t LogicDriverId = 1;
uint8_t LoopFlag = 0;
#ifdef FUNC_USB_EN
if(FsContext->gFsInfo.DevID == DEV_ID_USB)
{
SectorSizeMul = (HostStorGetBlockSize() / SECTOR_SIZE);
}
else
#endif
{
SectorSizeMul = 1;
}
// FS_DBG("SectorSizeMul: %d\n", (uint16_t)SectorSizeMul);
while(1)
{
LoopFlag = 0;
//read MBR
//if(!ReadBlock(BootSecNum, (uint8_t*)(FsContext->FAT_BUFFER), 1))
if(RES_OK != disk_read(FsContext->gFsInfo.DevID, (uint8_t*)(FsContext->FAT_BUFFER), BootSecNum, 1))
{
FS_DBG("ReadBlock() error!\n");
return FALSE;
}
FsContext->gFsInfo.CurrFATSecNum = BootSecNum;
#ifndef CANCEL_COMMON_SIGNATURE_JUDGMENT
if(*(uint16_t*)((FsContext->FAT_BUFFER) + SIGNATURE_OFFSET) != COMMON_SIGNATURE) //if 0x55aa
{
return FALSE;
}
#endif
for(IndexPtb = 0; IndexPtb < 4; IndexPtb++)
{
PARTITION* pPart = &((PARTITION*)((FsContext->FAT_BUFFER) + PARTITION_OFFSET))[IndexPtb];
if((pPart->PartitionType == 0x05) //Extended partition
&& ((ExtBootEntry == 0) || (IndexPtb >= ExtBootEntry)))
{
BootSecNum += Le32ToCpu(pPart->FirstSectorNum);
ExtBootEntry = IndexPtb + 1;
// FS_DBG("Extended partition bootSecNum:%ld\n", (uint32_t)BootSecNum);
LoopFlag = 1;
break;
}
//check the partition type and get the boot sector num
if(pPart->PartitionType == 0x04
|| pPart->PartitionType == 0x06
|| pPart->PartitionType == 0x0B
|| pPart->PartitionType == 0x0C
|| pPart->PartitionType == 0x01
|| pPart->PartitionType == 0x0E)
{
if(DriverId <= 1 || LogicDriverId == DriverId)
{
BootSecNum += Le32ToCpu(pPart->FirstSectorNum);
break;
}
LogicDriverId++;
}
}
if(LoopFlag)
{
continue;
}
if((IndexPtb == 4) && ((ExtBootEntry > 0) && (ExtBootEntry < 4)))
{
//if extended parttion failed,try again.
BootSecNum = 0;
continue;//<2F><><EFBFBD>ӶԵ<D3B6>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>Ч<EFBFBD><D0A7>չ<EFBFBD><D5B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E8B1B8>֧<EFBFBD><D6A7>
}
break;
}
if((DriverId > 1) && (LogicDriverId != DriverId))
{
return FALSE;
}
//read DBR
//if(!ReadBlock((BootSecNum * SectorSizeMul), (uint8_t*)(FsContext->FAT_BUFFER), 1))
if(RES_OK != disk_read(FsContext->gFsInfo.DevID, (uint8_t*)(FsContext->FAT_BUFFER), (BootSecNum * SectorSizeMul), 1))
{
return FALSE;
}
FsContext->gFsInfo.CurrFATSecNum = (BootSecNum * SectorSizeMul);
#ifndef CANCEL_COMMON_SIGNATURE_JUDGMENT
if(*(uint16_t*)((FsContext->FAT_BUFFER) + SIGNATURE_OFFSET) != COMMON_SIGNATURE) //if 0x55aa
{
return FALSE;
}
#endif
#define pzero_sector ((BOOT_SECTOR*)((FsContext->FAT_BUFFER)))
//updata device information
FsContext->gFsInfo.ClusterSize = pzero_sector->BPB_SecPerClus;
//get first sector of FAT
BPBRsvSectCnt = Le16ToCpu(pzero_sector->BPB_RsvdSecCnt);
FsContext->gFsInfo.FatStart = BPBRsvSectCnt + BootSecNum;
//get sectors of boot dir
if(pzero_sector->BPB_RootEntCnt != 0)
{
RootDirSectors = (Le16ToCpu(pzero_sector->BPB_RootEntCnt) * 32 + SECTOR_SIZE - 1) / SECTOR_SIZE;
}
else
{
RootDirSectors = 0;
}
//get FAT size
if(pzero_sector->BPB_FATSz16 != 0)
{
FatSize = Le16ToCpu(pzero_sector->BPB_FATSz16);
}
else
{
FatSize = Le32ToCpu(pzero_sector->BPB_FATSz32);
}
//get total cluster
if(pzero_sector->BPB_TotSec16 != 0)
{
TotalSectors = Le16ToCpu(pzero_sector->BPB_TotSec16);
}
else
{
TotalSectors = Le32ToCpu(pzero_sector->BPB_TotSec32);
}
temp2 = (TotalSectors - (BPBRsvSectCnt + FatSize * pzero_sector->BPB_NumFATs + RootDirSectors)) / FsContext->gFsInfo.ClusterSize;
// FS_DBG("temp2:%ld\n", (uint32_t)temp2);
if(temp2 < 4085)
{
FS_DBG("FAT12\n");
FsContext->gFsInfo.IsCpatFS = FALSE; //FAT12
return TRUE;
}
else if(temp2 < 65525)
{
FS_DBG("FAT16\n");
FsContext->gFsInfo.FAT32 = 0; //FAT16
FsContext->gFsInfo.IsCpatFS = TRUE;
}
else
{
//FAT32<33>豸BPB_RootEntCnt/BPB_TotSec16/BPB_FATSz16<31><36>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>
if(memcmp((uint8_t*)((FsContext->FAT_BUFFER) + 0x36), "FAT16\0\0\0", 8) == 0)
{
//<2F>ͻ<EFBFBD><CDBB><EFBFBD>һ<EFBFBD><D2BB>U<EFBFBD><55>(USB<53><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29><><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD><DDBC><EFBFBD><EFBFBD>ó<EFBFBD><C3B3>Ĵ<EFBFBD><C4B4><EFBFBD>ĿӦ<C4BF><D3A6>ΪFAT32<33><32>ʵ<EFBFBD><CAB5>ΪFAT16ϵͳ<CFB5><CDB3>Ϊ֧<CEAA><D6A7><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><E8B1B8><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>˴<EFBFBD><CBB4><EFBFBD>
FS_DBG("FAT16\n");
FsContext->gFsInfo.FAT32 = 0;
}
else
{
FS_DBG("FAT32\n");
FsContext->gFsInfo.FAT32 = 1; //FAT32
}
FsContext->gFsInfo.IsCpatFS = TRUE;
}
FsContext->gFsInfo.DataStart = FsContext->gFsInfo.FatStart + (FatSize * pzero_sector->BPB_NumFATs) + RootDirSectors; //the first sector of data
// get max cluster number in this drive.
//FsContext->gFsInfo.MaxCluster = ((TotalSectors - FsContext->gFsInfo.DataStart) / FsContext->gFsInfo.ClusterSize) + 2;
FsContext->gFsInfo.MaxCluster = temp2 + 2;
//get the data start and boot dir start
if(FsContext->gFsInfo.FAT32)
{
FsContext->gFsInfo.RootStart = FsContext->gFsInfo.DataStart + (Le32ToCpu(pzero_sector->BPB_RootClus) - 2) * FsContext->gFsInfo.ClusterSize;
}
else
{
FsContext->gFsInfo.RootStart = FsContext->gFsInfo.FatStart + FatSize * pzero_sector->BPB_NumFATs; //FAT16 the first sector of root dir
}
FsContext->gFsInfo.ClusterSize *= SectorSizeMul;
// RootDirSectors *= SectorSizeMul;
FsContext->gFsInfo.FatStart *= SectorSizeMul;
FsContext->gFsInfo.DataStart *= SectorSizeMul;
FsContext->gFsInfo.MaxSector = (BootSecNum + TotalSectors) * SectorSizeMul;
FsContext->gFsInfo.RootStart *= SectorSizeMul;
// FS_DBG("*************UDisk virtual params******************\n");
// FS_DBG("ClusterSize:%ld\n", (uint32_t)FsContext->gFsInfo.ClusterSize);
// FS_DBG("RootDirSectors:%ld\n", (uint32_t)RootDirSectors);
// FS_DBG("FatStart:%ld\n", (uint32_t)FsContext->gFsInfo.FatStart);
// FS_DBG("RootStart:%ld\n", (uint32_t)FsContext->gFsInfo.RootStart);
// FS_DBG("DataStart:%ld\n", (uint32_t)FsContext->gFsInfo.DataStart);
// FS_DBG("MaxCluster:%ld\n", (uint32_t)FsContext->gFsInfo.MaxCluster);
// FS_DBG("*****************************************************\n\n");
return TRUE;
}