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 + -
显示快捷键?