📄 bootpart.cpp
字号:
}
pPartState->dwDataPointer = dwNextPtrValue;
return(TRUE);
}
/* BP_OpenPartition
*
* Opens/creates a partition depending on the creation flags. If it is opening
* and the partition has already been opened, then it returns a handle to the
* opened partition. Otherwise, it loads the state information of that partition
* into memory and returns a handle.
*
* ENTRY
* dwStartSector - Logical sector to start the partition. NEXT_FREE_LOC if none
* specified. Ignored if opening existing partition.
* dwNumSectors - Number of logical sectors of the partition. USE_REMAINING_SPACE
* to indicate to take up the rest of the space on the flash for that partition (should
* only be used when creating extended partitions). This parameter is ignored
* if opening existing partition.
* dwPartType - Type of partition to create/open.
* fActive - TRUE indicates to create/open the active partition. FALSE for
* inactive.
* dwCreationFlags - PART_CREATE_NEW to create only. Fail if it already
* exists. PART_OPEN_EXISTING to open only. Fail if it doesn't exist.
* PART_OPEN_ALWAYS creates if it does not exist and opens if it
* does exist.
*
* EXIT
* Handle to the partition on success. INVALID_HANDLE_VALUE on error.
*/
HANDLE BP_OpenPartition(DWORD dwStartSector, DWORD dwNumSectors, DWORD dwPartType, BOOL fActive, DWORD dwCreationFlags)
{
DWORD dwPartIndex;
BOOL fExists;
RETAILMSG(1, (TEXT("OpenPartition: dwStartSector = 0x%x.\r\n"), dwStartSector));
RETAILMSG(1, (TEXT("OpenPartition: dwNumSectors = 0x%x.\r\n"), dwNumSectors));
RETAILMSG(1, (TEXT("OpenPartition: dwPartType = 0x%x.\r\n"), dwPartType));
RETAILMSG(1, (TEXT("OpenPartition: fActive = 0x%x.\r\n"), fActive));
RETAILMSG(1, (TEXT("OpenPartition: dwCreationFlags = 0x%x.\r\n"), dwCreationFlags));
ASSERT (g_pbMBRSector);
if (!IsValidMBR()) {
DWORD dwFlags = 0;
if (dwCreationFlags == PART_OPEN_EXISTING) {
RETAILMSG(1, (TEXT("OpenPartition: Invalid MBR. Cannot open existing partition 0x%x.\r\n"), dwPartType));
return INVALID_HANDLE_VALUE;
}
RETAILMSG(1, (TEXT("OpenPartition: Invalid MBR. Formatting flash.\r\n")));
if (g_FlashInfo.flashType == NOR) {
dwFlags |= FORMAT_SKIP_BLOCK_CHECK;
}
// BP_LowLevelFormat (0, g_FlashInfo.dwNumBlocks, dwFlags);
BP_LowLevelFormat (SECTOR_TO_BLOCK(dwStartSector), dwNumSectors/(SECTORS_PER_SUPAGE*PAGES_PER_SUBLK), dwFlags);
dwPartIndex = 0;
fExists = FALSE;
}
else {
fExists = GetPartitionTableIndex(dwPartType, fActive, &dwPartIndex);
}
// RETAILMSG(1, (TEXT("OpenPartition: Partition Exists=0x%x for part 0x%x.\r\n"), fExists, dwPartType));
if (fExists) {
// Partition was found.
if (dwCreationFlags == PART_CREATE_NEW)
return INVALID_HANDLE_VALUE;
if (g_partStateTable[dwPartIndex].pPartEntry == NULL) {
// Open partition. If this is the boot section partition, then file pointer starts after MBR
g_partStateTable[dwPartIndex].pPartEntry = (PPARTENTRY)(g_pbMBRSector + PARTTABLE_OFFSET + sizeof(PARTENTRY)*dwPartIndex);
g_partStateTable[dwPartIndex].dwDataPointer = 0;
}
return (HANDLE)&g_partStateTable[dwPartIndex];
}
else {
// If there are already 4 partitions, or creation flag specified OPEN_EXISTING, fail.
if ((dwPartIndex == NUM_PARTS) || (dwCreationFlags == PART_OPEN_EXISTING))
return INVALID_HANDLE_VALUE;
// Create new partition
return CreatePartition (dwStartSector, dwNumSectors, dwPartType, fActive, dwPartIndex);
}
return INVALID_HANDLE_VALUE;
}
/* BP_SetDataPointer
*
* Sets the data pointer of a particular partition. Data pointer stores the logical
* byte address where the next read or write will occur.
*
* ENTRY
* hPartition - handle to the partition
* dwAddress - Address to set data pointer to
*
* EXIT
* TRUE on success
*/
BOOL BP_SetDataPointer (HANDLE hPartition, DWORD dwAddress)
{
if (hPartition == INVALID_HANDLE_VALUE)
return FALSE;
RETAILMSG(1,(TEXT("BP_SetDataPointer at 0x%x\r\n"), dwAddress));
PPARTSTATE pPartState = (PPARTSTATE) hPartition;
if (dwAddress >= pPartState->pPartEntry->Part_TotalSectors * g_FlashInfo.wDataBytesPerSector)
{
RETAILMSG(1,(TEXT("pPartState->pPartEntry->Part_TotalSectors = 0x%x\r\n"), pPartState->pPartEntry->Part_TotalSectors));
RETAILMSG(1,(TEXT("g_FlashInfo.wDataBytesPerSector = 0x%x\r\n"), g_FlashInfo.wDataBytesPerSector));
RETAILMSG(1,(TEXT("pPartState->pPartEntry->Part_TotalSectors * g_FlashInfo.wDataBytesPerSector = 0x%x\r\n"), pPartState->pPartEntry->Part_TotalSectors * g_FlashInfo.wDataBytesPerSector));
return FALSE;
}
pPartState->dwDataPointer = dwAddress;
return TRUE;
}
/* BP_SetPhysDataPointer
*
* Sets the data pointer of a particular partition. This function compensates
* for bad and reserved blocks, and accounts for them in the supplied address.
* This behavior is useful on NOR flash when locating data based on statically
* mapped virtual addresses that do not account for reserved ranges.
*
* ENTRY
* hPartition - handle to the partition
* dwAddress - Physical address to set data pointer to, zero-based from the
* partition start.
*
* EXIT
* TRUE on success
*/
BOOL BP_SetPhysDataPointer (HANDLE hPartition, DWORD dwPhysAddress)
{
if (hPartition == INVALID_HANDLE_VALUE) {
return FALSE;
}
// RETAILMSG(1,(TEXT("BP_SetPhysDataPointer at 0x%x\r\n"), dwPhysAddress));
return BP_SetDataPointer(hPartition, dwPhysAddress);
}
/* BP_GetPartitionInfo
*
* Get the partition entry for an open partition.
*
* ENTRY
* hPartition - handle to the partition
*
* EXIT
* The partition entry
*/
PPARTENTRY BP_GetPartitionInfo (HANDLE hPartition)
{
if (!hPartition)
return NULL;
return ((PPARTSTATE)hPartition)->pPartEntry;
}
/* BP_Init
*
* Sets up locations for various objects in memory provided by caller
*
* ENTRY
* pMemory - pointer to memory for storing objects
* dwSize - size of the memory
* lpActiveReg - used by FMD_Init. NULL if not needed.
* pRegIn - used by FMD_Init. NULL if not needed.
* pRegOut - used by FMD_Init. NULL if not needed.
*
* EXIT
* TRUE on success
*/
BOOL BP_Init (LPBYTE pMemory, DWORD dwSize, LPCTSTR lpActiveReg, PPCI_REG_INFO pRegIn, PPCI_REG_INFO pRegOut)
{
// DWORD dwBufferSize;
if (!pMemory) {
RETAILMSG(1,(TEXT("BP_Init Fails No memory fails!!!\r\n")));
return FALSE;
}
if (!FMD_Init (lpActiveReg, pRegIn, pRegOut))
return FALSE;
if (!FMD_GetInfo (&g_FlashInfo)) {
RETAILMSG(1,(TEXT("BP_Init Fails FMD_GetInfo fails!!!\r\n")));
return FALSE;
}
// Check to make sure size is enough for one sector, one block, and sectorinfo buffer for one block
g_dwDataBytesPerBlock = g_FlashInfo.wDataBytesPerSector * g_FlashInfo.wSectorsPerBlock;
// PocketMory Version doesn't need sector info buffer.
// dwBufferSize = g_FlashInfo.wDataBytesPerSector + g_dwDataBytesPerBlock +
// g_FlashInfo.wSectorsPerBlock * sizeof(SectorInfo);
// if (dwSize < dwBufferSize) {
// RETAILMSG(1,(TEXT("BP_Init Fails buffer size = %x < required = %x!!!\r\n"),dwSize,dwBufferSize));
// return FALSE;
// }
for (int i = 0; i < NUM_PARTS; i++) {
g_partStateTable[i].pPartEntry= NULL;
g_partStateTable[i].dwDataPointer = 0;
}
g_pbMBRSector = pMemory; //size = g_FlashInfo.wDataBytesPerSector;
g_pbBlock = pMemory + g_FlashInfo.wDataBytesPerSector; //size = g_dwDataBytesPerBlock;
g_pSectorInfoBuf = (PSectorInfo)(g_pbBlock + g_dwDataBytesPerBlock); //size = g_FlashInfo.wSectorsPerBlock * sizeof(SectorInfo);
g_dwLastLogSector = 0;
return TRUE;
}
/* BP_LowLevelFormat
*
* Called when preparing flash for a multiple-BIN download.
* Erases, verifies, and writes logical sector numbers in the range to be written.
*
* ENTRY
* dwStartBlock - starting physical block for format
* dwNumBlocks - number of physical blocks to format
* dwFlags - Flags used in formatting.
*
* EXIT
* TRUE returned on success and FALSE on failure.
*/
BOOL BP_LowLevelFormat(DWORD dwStartBlock, DWORD dwNumBlocks, DWORD dwFlags)
{
DWORD nBlockNum;
//dwNumBlocks = min (dwNumBlocks, g_FlashInfo.dwNumBlocks);
RETAILMSG(1,(TEXT("Enter LowLevelFormat [0x%x, 0x%x].\r\n"), dwStartBlock, dwStartBlock + dwNumBlocks - 1));
// Erase all the flash blocks.
#if 0
if (!EraseBlocks(dwStartBlock, dwNumBlocks, dwFlags))
return(FALSE);
#endif
RETAILMSG(1,(TEXT("BP_LowLevelFormat: // Erase all the flash blocks.\r\n")));
for (nBlockNum = dwStartBlock ; nBlockNum < dwStartBlock+ dwNumBlocks; nBlockNum++)
{
//RETAILMSG(1,(TEXT("BP_LowLevelFormat: // Erase all the flash blocks.-#\r\n")));
if (!FMD_EraseBlock(nBlockNum))
{
return(FALSE);
}
}
RETAILMSG(1,(TEXT("BP_LowLevelFormat: // Erase all the flash blocks.-End\r\n")));
// Determine first good starting block
#if 0
while (IS_BLOCK_UNUSABLE (dwStartBlock) && dwStartBlock < g_FlashInfo.dwNumBlocks) {
dwStartBlock++;
}
if (dwStartBlock >= g_FlashInfo.dwNumBlocks) {
RETAILMSG(1,(TEXT("BP_LowLevelFormat: no good blocks\r\n")));
return FALSE;
}
#endif
// MBR goes in the first sector of the starting block. This will be logical sector 0.
g_dwMBRSectorNum = dwStartBlock * g_FlashInfo.wSectorsPerBlock;
// Create an MBR.
CreateMBR();
RETAILMSG (1, (TEXT("Done.\r\n\r\n")));
return(TRUE);
}
typedef struct
{
GUID guidReserved;
DWORD dwReserved1;
DWORD dwReserved2;
DWORD dwReserved3;
DWORD dwReserved4;
DWORD dwReserved5;
DWORD dwReserved6;
DWORD dwReserved7;
DWORD dwReserved8;
DWORD dwReserved9;
DWORD dwReserved10;
DWORD dwUpdateModeFlag;
} IMGFS_BOOT_SECTOR, *PIMGFS_BOOT_SECTOR;
// --------------------------------------------------------------------
// --------------------------------------------------------------------
BOOL BP_ReadLogicalSector(HANDLE hPartition, DWORD dwSector, LPBYTE lpBuffer)
{
static PVOID hFAL = NULL;
PPARTSTATE pPartState = (PPARTSTATE) hPartition;
if (INVALID_HANDLE_VALUE == hPartition) {
return FALSE;
}
return FMD_ReadSector(dwSector + pPartState->pPartEntry->Part_StartSector, lpBuffer, NULL, 1);
}
// --------------------------------------------------------------------
// --------------------------------------------------------------------
BOOL BP_GetUpdateModeFlag(BOOL *pfUpdateMode)
{
// sectors will be 4KB at the most
static BYTE sector[0x1000];
if (NULL == pfUpdateMode) {
return FALSE;
}
// open the imgfs partition
HANDLE hPartition = BP_OpenPartition(0, 0, PART_IMGFS, FALSE, PART_OPEN_EXISTING);
if (INVALID_HANDLE_VALUE == hPartition) {
// try again with fActive = TRUE
hPartition = BP_OpenPartition(0, 0, PART_IMGFS, TRUE, PART_OPEN_EXISTING);
}
if (INVALID_HANDLE_VALUE == hPartition) {
// there is probably no IMGFS partition
RETAILMSG(1, (TEXT("BP_GetUpdateModeFlag: failed to open IMGFS partition\r\n")));
return FALSE;
}
// read logical sector zero of the imgfs partition
if (!BP_ReadLogicalSector(hPartition, 0, sector)) {
RETAILMSG(1, (TEXT("BP_GetUpdateModeFlag: failed to read bootsector of IMGFS partition\r\n")));
return FALSE;
}
*pfUpdateMode = ((PIMGFS_BOOT_SECTOR)sector)->dwUpdateModeFlag;
RETAILMSG(1, (L"BP_GetUpdateModeFlag: fUpdateMode=%d\r\n", *pfUpdateMode));
//if(*pfUpdateMode!=1) *pfUpdateMode=0;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -