bootpart.cpp
来自「SAMSUNG S3C6410 CPU BSP for winmobile6」· C++ 代码 · 共 623 行 · 第 1/2 页
CPP
623 行
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <bootpart.h>
#include "bppriv.h"
LPBYTE g_pbMBRSector = NULL;
LPBYTE g_pbBlock = NULL;
DWORD g_dwMBRSectorNum = INVALID_ADDR;
FlashInfo g_FlashInfo;
PARTSTATE g_partStateTable[NUM_PARTS];
PSectorInfo g_pSectorInfoBuf;
DWORD g_dwLastLogSector; // Stores the last valid logical sector
DWORD g_dwDataBytesPerBlock;
DWORD g_dwLastWrittenLoc; // Stores the byte address of the last physical flash address written to
#define Log2Phys(sector) (sector)
static BOOL IsValidMBR()
{
// Check to see if the MBR is valid
// MBR block is always located at logical sector 0
g_dwMBRSectorNum = 0; //GetMBRSectorNum();
RETAILMSG (1, (TEXT("IsValidMBR: MBR sector = 0x%x\r\n"), g_dwMBRSectorNum));
if ((g_dwMBRSectorNum == INVALID_ADDR) || !FMD_ReadSector (g_dwMBRSectorNum, g_pbMBRSector, NULL, 1)) {
return FALSE;
}
#if 0 // for debugging
// data for MBR sector
{
int i;
RETAILMSG(1, (L"=====================================================\r\n"));
for (i = 0; i < 0x800; i++) {
if (i % 16 == 0)
RETAILMSG(1, (L"0x%x: ", g_pbMBRSector+i));
RETAILMSG(1, (L"%x%x ", (g_pbMBRSector[i]>>4)&0xf, g_pbMBRSector[i]&0xf));
if ((i + 1) % 16 == 0)
RETAILMSG(1, (L"\r\n"));
}
RETAILMSG(1, (L"=====================================================\r\n"));
}
// data for partition entry
LPBYTE pbBuf = g_pbMBRSector + 512 - 0x42;
RETAILMSG(1, (L"g_pbMBRSector = 0x%x\r\n", g_pbMBRSector));
for (DWORD i = 0; i < 0x40; i++) {
if (i % 16 == 0)
RETAILMSG(1, (L"0x%x: ", pbBuf+i));
RETAILMSG(1, (L"%x%x ", (pbBuf[i] >> 4) & 0x0f, pbBuf[i] & 0x0f));
if ((i + 1) % 16 == 0)
RETAILMSG(1, (L"\r\n"));
}
#endif
return ((g_pbMBRSector[0] == 0xE9) &&
(g_pbMBRSector[1] == 0xfd) &&
(g_pbMBRSector[2] == 0xff) &&
(g_pbMBRSector[SECTOR_SIZE-2] == 0x55) &&
(g_pbMBRSector[SECTOR_SIZE-1] == 0xAA));
}
static BOOL IsValidPart (PPARTENTRY pPartEntry)
{
return (pPartEntry->Part_FileSystem != 0xff) && (pPartEntry->Part_FileSystem != 0);
}
/* GetPartitionTableIndex
*
* Get the partition index for a particular partition type and active status.
* If partition is not found, then the index of the next free partition in the
* partition table of the MBR is returned.
*
*
* ENTRY
* dwPartType - type of partition
* fActive - TRUE indicates the active partition. FALSE indicates inactive.
*
* EXIT
* pdwIndex - Contains the index of the partition if found. If not found,
* contains the index of the next free partition
* returns TRUE if partition found. FALSE if not found.
*/
static BOOL GetPartitionTableIndex (DWORD dwPartType, BOOL fActive, PDWORD pdwIndex)
{
PPARTENTRY pPartEntry = (PPARTENTRY)(g_pbMBRSector + PARTTABLE_OFFSET);
DWORD iEntry = 0;
for (iEntry = 0; iEntry < NUM_PARTS; iEntry++, pPartEntry++) {
if ((pPartEntry->Part_FileSystem == dwPartType) && (((pPartEntry->Part_BootInd & PART_IND_ACTIVE) != 0) == fActive)) {
*pdwIndex = iEntry;
return TRUE;
}
if (!IsValidPart (pPartEntry)) {
*pdwIndex = iEntry;
return FALSE;
}
}
return FALSE;
}
/* BP_ReadData
*
* Reads data from the partition starting at the data pointer. Call fails
* if length of the buffer is too long (i.e. trying to read past the end
* of the partition)
*
* ENTRY
* hPartition - handle to the partition
* pbBuffer - pointer to buffer of data to read
* dwLength - number of bytes to read
*
* EXIT
* TRUE on success
*/
BOOL BP_ReadData(HANDLE hPartition, LPBYTE pbBuffer, DWORD dwLength)
{
if (hPartition == INVALID_HANDLE_VALUE)
return FALSE;
DWORD dwNumSects;
static LPBYTE pbSector = g_pbBlock;
PPARTSTATE pPartState = (PPARTSTATE) hPartition;
DWORD dwNextPtrValue = pPartState->dwDataPointer + dwLength;
if (!pbBuffer || !pbSector || dwLength == 0)
return(FALSE);
// RETAILMSG(1,(TEXT("ReadData: Start = 0x%x, Length = 0x%x.\r\n"), pPartState->dwDataPointer, dwLength));
// Check to make sure buffer size is within limits of partition
if (((dwNextPtrValue - 1) / g_FlashInfo.wDataBytesPerSector) >= pPartState->pPartEntry->Part_TotalSectors) {
RETAILMSG (1, (TEXT("ReadData: trying to read past end of partition.\r\n")));
return FALSE;
}
// Get the starting physical sector
DWORD dwSectorAddr = Log2Phys (pPartState->dwDataPointer / g_FlashInfo.wDataBytesPerSector + pPartState->pPartEntry->Part_StartSector);
DWORD dwSector0 = dwSectorAddr;
DWORD dwLen0 = dwLength;
LPBYTE pbBuf0 = pbBuffer;
// If current pointer is not on a sector boundary, copy bytes up to the first sector boundary
DWORD dwOffsetSector = pPartState->dwDataPointer % g_FlashInfo.wDataBytesPerSector;
if (dwOffsetSector)
{
if (!FMD_ReadSector(dwSectorAddr, pbSector, NULL, 1))
{
RETAILMSG (1, (TEXT("ReadData: failed to read sector (0x%x).\r\n"), dwSectorAddr));
return(FALSE);
}
DWORD dwNumBytesRead = g_FlashInfo.wDataBytesPerSector - dwOffsetSector;
if (dwNumBytesRead > dwLength)
dwNumBytesRead = dwLength;
memcpy(pbBuffer, pbSector + dwOffsetSector, dwNumBytesRead);
dwLength -= dwNumBytesRead;
pbBuffer += dwNumBytesRead;
dwSectorAddr++;
}
// Compute sector length.
dwNumSects = (dwLength / g_FlashInfo.wDataBytesPerSector);
if (dwNumSects)
FMD_ReadSector(dwSectorAddr, pbBuffer, NULL, dwNumSects);
DWORD dwNumExtraBytes = (dwLength % g_FlashInfo.wDataBytesPerSector);
if (dwNumExtraBytes)
{
dwSectorAddr += dwNumSects;
pbBuffer += dwNumSects*g_FlashInfo.wDataBytesPerSector;
if (!FMD_ReadSector(dwSectorAddr, pbSector, NULL, 1))
{
RETAILMSG (1, (TEXT("ReadData: failed to read sector (0x%x).\r\n"), dwSectorAddr));
return(FALSE);
}
memcpy(pbBuffer, pbSector, dwNumExtraBytes);
}
#if 0
//dump if inside 10 sectors
if (pPartState->dwDataPointer < 10*512) {
RETAILMSG(1, (L"BP_ReadData: StartSector=0x%x, SectorOffset=0x%x, Leghth=0x%x",
dwSector0, dwOffsetSector, dwLen0));
DWORD dwAddr = pPartState->dwDataPointer;
DWORD dwOffset16 = dwOffsetSector % 16;
DWORD i;
if (dwOffset16 != 0) {
dwAddr -= dwOffset16;
RETAILMSG(1, (L"\r\nSector=0x%x(0x%x)",
dwSector0 + (dwAddr / 512),
(dwSector0 + (dwAddr / 512))*512));
RETAILMSG(1, (L"\r\n%x%x%x%x: ", (dwAddr >> 12) & 0x0f, (dwAddr >> 8) & 0x0f,
(dwAddr >> 4) & 0x0f, dwAddr & 0x0f));
for (i = 0; i < dwOffset16; i++, dwAddr++)
RETAILMSG(1, (L"__ "));
}
for (i = 0; i < dwLen0; i++, dwAddr++) {
if ((dwAddr % 16) == 0) {
if ((dwAddr % 512) == 0)
RETAILMSG(1, (L"\r\nSector=0x%x(0x%x)",
dwSector0 + (dwAddr / 512),
(dwSector0 + (dwAddr / 512))*512));
RETAILMSG(1, (L"\r\n%x%x%x%x: ", (dwAddr >> 12) & 0x0f, (dwAddr >> 8) & 0x0f,
(dwAddr >> 4) & 0x0f, dwAddr & 0x0f));
}
RETAILMSG(1, (L"%x%x ", (pbBuf0[i] >> 4) & 0x0f, pbBuf0[i] & 0x0f));
}
RETAILMSG(1, (L"\r\n"));
}
#endif
pPartState->dwDataPointer = dwNextPtrValue;
return(TRUE);
}
/* BP_WriteData
*
* Writes data to the partition starting at the data pointer. Call fails
* if length of the buffer is too long (i.e. trying to write past the end
* of the partition)
*
* ENTRY
* hPartition - handle to the partition
* pbBuffer - pointer to buffer of data to write
* dwLength - length in bytes of the buffer
*
* EXIT
* TRUE on success
*/
BOOL BP_WriteData(HANDLE hPartition, LPBYTE pbBuffer, DWORD dwLength)
{
if (hPartition == INVALID_HANDLE_VALUE)
return FALSE;
DWORD dwNumSects;
static LPBYTE pbSector = g_pbBlock;
PPARTSTATE pPartState = (PPARTSTATE) hPartition;
DWORD dwNextPtrValue = pPartState->dwDataPointer + dwLength;
if (!pbBuffer || !pbSector || dwLength == 0)
return(FALSE);
// RETAILMSG (1, (TEXT("WriteData: Start = 0x%x, Length = 0x%x.\r\n"), pPartState->dwDataPointer, dwLength));
// Check to make sure buffer size is within limits of partition
if (((dwNextPtrValue - 1) / g_FlashInfo.wDataBytesPerSector) >= pPartState->pPartEntry->Part_TotalSectors) {
RETAILMSG (1, (TEXT("ReadData: trying to read past end of partition.\r\n")));
return FALSE;
}
// Get the starting physical sector
DWORD dwSectorAddr = Log2Phys (pPartState->dwDataPointer / g_FlashInfo.wDataBytesPerSector + pPartState->pPartEntry->Part_StartSector);
// If current pointer is not on a sector boundary, copy bytes up to the first sector boundary
DWORD dwOffsetSector = pPartState->dwDataPointer % g_FlashInfo.wDataBytesPerSector;
if (dwOffsetSector)
{
if (!FMD_ReadSector(dwSectorAddr, pbSector, NULL, 1))
{
RETAILMSG (1, (TEXT("WriteData: failed to read sector (0x%x).\r\n"), dwSectorAddr));
return(FALSE);
}
DWORD dwNumBytesWrite = g_FlashInfo.wDataBytesPerSector - dwOffsetSector;
if (dwNumBytesWrite > dwLength)
dwNumBytesWrite = dwLength;
memcpy(pbSector + dwOffsetSector, pbBuffer, dwNumBytesWrite);
dwLength -= dwNumBytesWrite;
pbBuffer += dwNumBytesWrite;
if (!FMD_WriteSector(dwSectorAddr, pbSector, NULL, 1))
{
RETAILMSG(1, (TEXT("WriteData: faild to write sector (0x%x).\r\n"), dwSectorAddr));
return(FALSE);
}
dwSectorAddr++;
}
// Compute sector length.
dwNumSects = (dwLength / g_FlashInfo.wDataBytesPerSector);
if (dwNumSects)
FMD_WriteSector(dwSectorAddr, pbBuffer, NULL, dwNumSects);
DWORD dwNumExtraBytes = (dwLength % g_FlashInfo.wDataBytesPerSector);
if (dwNumExtraBytes)
{
dwSectorAddr += dwNumSects;
pbBuffer += dwNumSects*g_FlashInfo.wDataBytesPerSector;
if (!FMD_ReadSector(dwSectorAddr, pbSector, NULL, 1))
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?