mirror of
https://github.com/oopuuu/zTC1.git
synced 2025-12-17 07:28:14 +08:00
287 lines
7.9 KiB
C
287 lines
7.9 KiB
C
/////////////////////////////////////////////////////////////////////////
|
||
// 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;
|
||
}
|
||
|
||
|
||
|