⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nand.c

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 C
📖 第 1 页 / 共 4 页
字号:

    // Calculate the physical block range for the NK image
    startBlockID = IMAGE_BOOT_NKIMAGE_NAND_OFFSET / flashInfo.dwBytesPerBlock;
    endBlockID = startBlockID + (IMAGE_BOOT_NKIMAGE_NAND_SIZE / flashInfo.dwBytesPerBlock);
    
    // Set image load address
    pSectorBuf = (LPBYTE) OALPAtoUA(IMAGE_BOOT_NKIMAGE_RAM_PA_START);

    EdbgOutputDebugString("INFO: Copying NK image to RAM address 0x%x\r\n", pSectorBuf);

    lastPercentComplete = 0;
    
    // Copy NK from NAND flash to RAM
    for (blockID = startBlockID; blockID < endBlockID ; blockID++)
    {        
        // Skip bad blocks
        if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
        {
            EdbgOutputDebugString("INFO: Found bad NAND flash block [0x%x].\r\n", blockID);
            continue;
        }

        // Compute sector address based on current physical block
        startSectorAddr = blockID * flashInfo.wSectorsPerBlock;
        endSectorAddr = startSectorAddr + flashInfo.wSectorsPerBlock;
        
        for (sectorAddr = startSectorAddr; sectorAddr < endSectorAddr; sectorAddr++)
        {
            if (!FMD_ReadSector(sectorAddr, pSectorBuf, &sectorInfo, 1))
            {
                EdbgOutputDebugString("ERROR: Failed to update NK.\r\n");
                return(FALSE);
            }

            pSectorBuf += flashInfo.wDataBytesPerSector;
        }

        percentComplete =  100 * (blockID - startBlockID + 1) / (endBlockID - startBlockID);

        // If percentage complete has changed, show the progress
        if (lastPercentComplete != percentComplete)
        {
            lastPercentComplete = percentComplete;
            OEMWriteDebugByte('\r');
            EdbgOutputDebugString("INFO: Load is %d%% complete.", percentComplete);
        }

    }

    EdbgOutputDebugString("\r\nINFO: Copy of NK completed successfully.\r\n");

    
    return(TRUE);

}


//-----------------------------------------------------------------------------
//
//  Function:  NANDFormatNK
//
//  This function formats (erases) the NAND flash region reserved for OS 
//  images.
//
//  Parameters:
//      None.     
//
//  Returns:
//      TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NANDFormatNK(void)
{
    FlashInfo flashInfo;
    BLOCK_ID blockID, startBlockID, endBlockID;
    UINT32 percentComplete, lastPercentComplete;

    // Get NAND flash data bytes per sector.
    //
    if (!FMD_GetInfo(&flashInfo))
    {
        EdbgOutputDebugString("ERROR: Unable to get NAND flash information.\r\n");
        return(FALSE);
    }

    // Calculate the physical block range for the NK image
    startBlockID = IMAGE_BOOT_NKIMAGE_NAND_OFFSET / flashInfo.dwBytesPerBlock;
    endBlockID = startBlockID + (IMAGE_BOOT_NKIMAGE_NAND_SIZE / flashInfo.dwBytesPerBlock);

    EdbgOutputDebugString("INFO: Starting format of NAND NK region.\r\n");

    lastPercentComplete = 0;

    for (blockID = startBlockID; blockID < endBlockID ; blockID++)
    {
        // Is the block bad?
        //
        if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
        {
            EdbgOutputDebugString("\r\nINFO: Found bad NAND flash block [0x%x].\r\n", blockID);
            continue;
        }

        // Erase the block...
        //
        if (!FMD_EraseBlock(blockID))
        {
            EdbgOutputDebugString("\r\nERROR: Unable to erase NAND flash block 0x%x.\r\n", blockID);
            return(FALSE);
        }
        else
        {
            percentComplete = 100 * (blockID - startBlockID + 1) / (endBlockID - startBlockID);

            // If percentage complete has changed, show the progress
            if (lastPercentComplete != percentComplete)
            {
                lastPercentComplete = percentComplete;
                OEMWriteDebugByte('\r');
                EdbgOutputDebugString("INFO: Format is %d%% complete.", percentComplete);
            }
        }
    }

    EdbgOutputDebugString("\r\nINFO: Format of NAND NK region completed successfully.\r\n");

    
    return(TRUE);
}


//-----------------------------------------------------------------------------
//
//  Function:  NANDFormatAll
//
//  This function formats (erases) the entire NAND flash memory.
//
//  Parameters:
//      None.     
//
//  Returns:
//      TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NANDFormatAll(void)
{
    FlashInfo flashInfo;
    BLOCK_ID blockID, startBlockID, endBlockID;
    UINT32 percentComplete, lastPercentComplete;

    // Get NAND flash data bytes per sector.
    //
    if (!FMD_GetInfo(&flashInfo))
    {
        EdbgOutputDebugString("ERROR: Unable to get NAND flash information.\r\n");
        return(FALSE);
    }

    // Calculate the physical block range for the enrire NAND device
    startBlockID = 0;
    endBlockID = flashInfo.dwNumBlocks;

    EdbgOutputDebugString("INFO: Starting format of all NAND regions.\r\n");

    lastPercentComplete = 0;

    for (blockID = startBlockID; blockID < endBlockID ; blockID++)
    {
        // Is the block bad?
        //
        if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
        {
            EdbgOutputDebugString("INFO: Found bad NAND flash block [0x%x].\r\n", blockID);
            continue;
        }

        // Erase the block...
        //
        if (!FMD_EraseBlock(blockID))
        {
            EdbgOutputDebugString("ERROR: Unable to erase NAND flash block 0x%x.\r\n", blockID);
            return(FALSE);
        }
        else
        {
            percentComplete = 100 * (blockID - startBlockID + 1) / (endBlockID - startBlockID);

            // If percentage complete has changed, show the progress
            if (lastPercentComplete != percentComplete)
            {
                lastPercentComplete = percentComplete;
                OEMWriteDebugByte('\r');
                EdbgOutputDebugString("INFO: Format is %d%% complete.", percentComplete);
            }
        }
    }
    
    EdbgOutputDebugString("\r\nINFO: Format of all NAND regions completed successfully.\r\n");

    return(TRUE);
}


//------------------------------------------------------------------------------
//
//  Function:  NANDLoadEBootCFG
//
//  Retrieves bootloader configuration information (menu settings, etc.) from 
//  the NAND flash.
//
//  Parameters:
//      eBootCFG 
//          [out] Points to bootloader configuration that will be filled with
//          loaded data. 
//
//      cbBootCfgSize
//          [in] Size in bytes of the bootloader configuration.
//
//  Returns:
//      TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NANDLoadEBootCFG(BYTE *pBootCfg, DWORD cbBootCfgSize)
{
    BOOL rc = FALSE;
    FlashInfo flashInfo;
    BLOCK_ID blockID, startBlockID, endBlockID;
    SECTOR_ADDR sectorAddr;

    if (!FMD_GetInfo(&flashInfo))
    {
        EdbgOutputDebugString("ERROR: Unable to get NAND flash information.\r\n");
        return(FALSE);
    }

    // Calculate the physical block range for the boot configuration
    startBlockID = IMAGE_BOOT_BOOTCFG_NAND_OFFSET / flashInfo.dwBytesPerBlock;
    endBlockID = startBlockID + (IMAGE_BOOT_BOOTCFG_NAND_SIZE / flashInfo.dwBytesPerBlock);
    
    EdbgOutputDebugString("INFO: Loading boot configuration from NAND\r\n");
    
    // Find a good block and load the boot configuration
    for (blockID = startBlockID; (blockID < endBlockID) && (rc == FALSE) ; blockID++)
    {        
        // Skip bad blocks
        if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
        {
            EdbgOutputDebugString("INFO: Found bad NAND flash block [0x%x].\r\n", blockID);
            continue;
        }

        // Compute sector address based on current physical block
        sectorAddr = blockID * flashInfo.wSectorsPerBlock;

        rc = FMD_ReadSector(sectorAddr, sectorBuf, NULL, 1);
    }

    if (rc)
    {
        memcpy(pBootCfg, sectorBuf, cbBootCfgSize);
    }
    else
    {
        EdbgOutputDebugString("ERROR: Failed to load boot configuration from NAND\r\n");
    }

    return rc;
}


//------------------------------------------------------------------------------
//
//  Function:  NANDStoreEBootCFG
//
//  Stores bootloader configuration information (menu settings, etc.) to 
//  the NAND flash.
//
//  Parameters:
//      eBootCFG 
//          [out] Points to bootloader configuration that will be stored.
//
//      cbBootCfgSize
//          [in] Size in bytes of the bootloader configuration.
//
//  Returns:
//      TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NANDStoreEBootCFG(BYTE *pBootCfg, DWORD cbBootCfgSize)
{
    FlashInfo flashInfo;
    SectorInfo sectorInfo;
    BLOCK_ID blockID, startBlockID, endBlockID;
    SECTOR_ADDR sectorAddr, startSectorAddr, endSectorAddr;

    if (!FMD_GetInfo(&flashInfo))
    {
        EdbgOutputDebugString("ERROR: Unable to get NAND flash information.\r\n");
        return(FALSE);
    }

    memcpy(sectorBuf, pBootCfg, cbBootCfgSize);
    memset(sectorBuf + cbBootCfgSize, 0xFF, 2048 - cbBootCfgSize);

    sectorInfo.dwReserved1 = 0xFFFFFFFF;
    sectorInfo.bOEMReserved = 0x00;
    sectorInfo.bBadBlock = 0xFF;    
    sectorInfo.wReserved2 = 0xFFFF;

    // Calculate the physical block range for the boot configuration
    startBlockID = IMAGE_BOOT_BOOTCFG_NAND_OFFSET / flashInfo.dwBytesPerBlock;
    endBlockID = startBlockID + (IMAGE_BOOT_BOOTCFG_NAND_SIZE / flashInfo.dwBytesPerBlock);
    
    EdbgOutputDebugString("INFO: Storing boot configuration to NAND\r\n");
    
    // Erase range of NAND blocks reserved for boot configuration
    for (blockID = startBlockID; blockID < endBlockID; blockID++)
    {
        // Skip bad blocks
        if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
        {
            EdbgOutputDebugString("INFO: Found bad NAND flash block [0x%x].\r\n", blockID);
            continue;
        }

        // Erase the block...
        if (!FMD_EraseBlock(blockID))
        {
            EdbgOutputDebugString("ERROR: Unable to erase NAND flash block [0x%x].\r\n", blockID);
            return FALSE;
        }
    }

    // Find a good block and store the boot configuration
    for (blockID = startBlockID; blockID < endBlockID ; blockID++)
    {        
        // Skip bad blocks
        if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
        {
            EdbgOutputDebugString("INFO: Found bad NAND flash block [0x%x].\r\n", blockID);
            continue;
        }

        // Compute sector address based on current physical block
        startSectorAddr = blockID * flashInfo.wSectorsPerBlock;
        endSectorAddr = startSectorAddr + flashInfo.wSectorsPerBlock;

        // Write out the boot configuration to all sectors as filler so the
        // NAND FMD does not try to map it later
        for (sectorAddr = startSectorAddr; sectorAddr < endSectorAddr; sectorAddr++)
        {
            if (!FMD_WriteSector(sectorAddr, sectorBuf, &sectorInfo, 1))
            {
                EdbgOutputDebugString("ERROR: Failed to update EBOOT.\r\n");
                return FALSE;
            }
        }
    }

    EdbgOutputDebugString("INFO: Successfully stored boot configuration to NAND\r\n");

    return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -