bootpart.cpp

来自「SAMSUNG S3C6410 CPU BSP for winmobile6」· C++ 代码 · 共 623 行 · 第 1/2 页

CPP
623
字号
        {
            RETAILMSG (1, (TEXT("WriteData: failed to read sector (0x%x).\r\n"), dwSectorAddr));
            return(FALSE);
        }
        memcpy(pbSector, pbBuffer, dwNumExtraBytes);
        
        if (!FMD_WriteSector(dwSectorAddr, pbSector, NULL, 1))
        {
        	RETAILMSG(1, (TEXT("WriteData: failed to read sector (0x%x).\r\n"), dwSectorAddr));
        	return(FALSE);
        }
    }
    
    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;

        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);
            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)
        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;
    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)
{
    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 + =
减小字号Ctrl + -
显示快捷键?