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

📄 nand.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    dwBlock = FindFirstGoodBlock(1);

    OALMSG(OAL_FUNC, (TEXT("dwRegionStart:%X dwRegionLength:%X dwImageStart:%X dwNumSectors: %d dwBlock %d\r\n"), 
                dwRegionStart, dwRegionLength, dwImageStart, dwNumSectors, dwBlock));

    for(; dwNumSectors > 0; dwBlock++)
    {
        if(dwBlock >= g_FlashInfo.dwNumBlocks)
        {
            OALMSG(OAL_ERROR, (TEXT("ERROR: No available blocks left! Unwritten sectors: %d \r\n"), dwNumSectors));
            return FALSE;
        }

        dwBlockStatus = FMD_GetBlockStatus(dwBlock);
        
        // Skip bad blocks
        if((dwBlockStatus & BLOCK_STATUS_BAD) || (dwBlockStatus & BLOCK_STATUS_UNKNOWN))
        {
            OALMSG(OAL_INFO, (TEXT("INFO: block %d bad! Skipping block.\r\n"), dwBlock));
            continue;
        }

        // Prepare block
        if( FMD_EraseBlock(dwBlock) != TRUE || 
            FMD_SetBlockStatus(dwBlock, (BLOCK_STATUS_READONLY | BLOCK_STATUS_RESERVED)) != TRUE)
        {
            OALMSG(OAL_ERROR, (TEXT("Prepare block %d status failed or un-erasable! Skip block.\r\n"), dwBlock));
            if(FMD_SetBlockStatus(dwBlock, BLOCK_STATUS_BAD) != TRUE)
            {
                OALMSG(OAL_ERROR, (TEXT("ERROR: Unable to set block %d status! Skipping NAND program.\r\n"), dwBlock));
                return FALSE;
            }
            continue;
        }

        // Write image to block
        dwStartSectorAddr = dwBlock * g_FlashInfo.wSectorsPerBlock;
        nSectors = (dwNumSectors > g_FlashInfo.wSectorsPerBlock)? g_FlashInfo.wSectorsPerBlock : dwNumSectors;
    
        OALMSG(1|OAL_FUNC, (TEXT("Writing block %d sector 0x%X numSectors %d!\r\n"), 
                dwBlock, dwStartSectorAddr, nSectors));

        if(FMD_WriteSector(dwStartSectorAddr, (LPBYTE)dwImageStart,    NULL, nSectors) != TRUE)
        {
            OALMSG(OAL_ERROR, (TEXT("Writing to block %d failed!\r\n"), dwBlock));
            if(FMD_SetBlockStatus(dwBlock, BLOCK_STATUS_BAD) != TRUE)
            {
                OALMSG(OAL_ERROR, (TEXT("ERROR: Unable to set block %d status! Skipping NAND program.\r\n"), dwBlock));
                return FALSE;
            }
            continue;
        }
        else
        {
            dwNumSectors -= nSectors;
            dwImageStart += nSectors * g_FlashInfo.wDataBytesPerSector;
        }
    }

    OALMSG(OAL_INFO, (TEXT("INFO: Programming EBOOT to NAND cmplete.\r\n")));

    OALMSG(OAL_FUNC, (TEXT("WriteEBootRegionToNand-\r\n")));
    return TRUE;
}

//-----------------------------------------------------------------------------
//
//  FUNCTION:        WriteNandLoaderRegionToNand
//
//  DESCRIPTION:    Writes Nand Loader binary region to NAND. 
//                    Note: This assumes that the block0 to be valid and good. 
//
//  PARAMETERS:        
//                    pBootCfg - Ptr to EBOOT configuration structure.
//                                Ignored.
//                    
//  RETURNS:        TRUE for success. FALSE for failure.
//
//-----------------------------------------------------------------------------
static BOOL WriteNandLoaderRegionToNand(BOOT_CFG *pBootCfg)
{
    extern MultiBINInfo g_BINRegionInfo;
    FILESentry *pFILES;
    DWORD blockStatus;
    DWORD dwImageSize;
    DWORD dwImageStart;
    DWORD dwNumSectors;
    BYTE nCount;
    
    OALMSG(OAL_FUNC, (TEXT("WriteNandLoaderRegionToNand+\r\n")));
    if(g_fNandExists != TRUE)
    {
        OALMSG(OAL_ERROR, (TEXT("WARNING: NAND device doesn't exist - unable to write image.\r\n")));
        return FALSE;
    }

    // Check for presence of nandloader file
    for(nCount = 0; nCount < g_BINRegionInfo.dwNumRegions; nCount++)
    {
        if((pFILES = (FILESentry *)GetNandLoaderFilePointer(g_BINRegionInfo.Region[nCount].dwRegionStart, g_BINRegionInfo.Region[nCount].dwRegionLength)) == NULL)
        {
            OALMSG(OAL_ERROR, (TEXT("ERROR: No NANDLoader image file found! Skipping NAND program.\r\n")));
            return FALSE;
        }
    }

    if(OEMIsFlashAddr(g_BINRegionInfo.Region[nCount].dwRegionStart))
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: Image built for FLASH. Skipping NAND program.\r\n")));
        return FALSE;
    }
    
    dwImageStart = (DWORD)OEMMapMemAddr(g_BINRegionInfo.Region[nCount].dwRegionStart, pFILES->ulLoadOffset);
    // Check nandloader image file size
    if(pFILES->nCompFileSize != pFILES->nRealFileSize)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: NandLoader Image should not be compressed! Skipping NAND program.\r\n")));
        return FALSE;
    }

    if((dwImageSize = pFILES->nRealFileSize) > NAND_LOADER_IMAGE_SIZE)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: Image size(0x%X) greater than reserved(%x). Skipping NAND program.\r\n"), 
                            pFILES->nRealFileSize, NAND_LOADER_IMAGE_SIZE));
        return FALSE;
    }
    dwNumSectors = NAND_IMAGE_NUM_SECTOR(dwImageSize, g_FlashInfo.wDataBytesPerSector);

    // first erase the flash and set block info.
    OALMSG(OAL_INFO, (TEXT("INFO: Erasing NandLoader NAND flash region...\r\n")));

    if(FMD_EraseBlock(0) != TRUE)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: WriteNandLoaderRegionToNand: cannot erase block 0!\r\n")));
        return FALSE;
    }
    g_fBlock0Erased = TRUE;

    blockStatus = FMD_GetBlockStatus(0);
    if((blockStatus & BLOCK_STATUS_UNKNOWN))
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: Cannot get block 0 status! Skipping NAND program.\r\n")));
        return FALSE;
    }
    if((blockStatus & BLOCK_STATUS_BAD))
    {
#if !IGNORE_OEM_RESERVED_BAD_BLOCKS
        OALMSG(OAL_ERROR, (TEXT("ERROR: Block 0 BAD! Skipping NAND program.\r\n")));
        return FALSE;
#endif
    }
    // Set block as OEM_RESERVED and READONLY
    if(FMD_SetBlockStatus(0, (BLOCK_STATUS_READONLY | BLOCK_STATUS_RESERVED)) != TRUE)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: Unable to set block 0 status! Skipping NAND program.\r\n")));
        return FALSE;
    }

    OALMSG(OAL_FUNC, (TEXT("INFO: Writing NandLoader image to flash:\r\n")));
    OALMSG(OAL_FUNC, (TEXT("imageStart:%X imageSize:%X numSectors: %d\r\n"), 
                dwImageStart, dwImageSize, dwNumSectors));
    
    if(FMD_WriteSector(0, (LPBYTE)(dwImageStart), NULL, dwNumSectors ) != TRUE)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: failed to write NandLoader image (start=0x%x, length=0x%x).\r\n"), dwImageStart, dwImageSize));
        return FALSE;
    }

#if DEBUG
    if(FMD_ReadSector(0, (LPBYTE)(EBOOT_FCACHE_START + 0x00100000), NULL, dwNumSectors ) != TRUE)
    {
        OALMSG(OAL_INFO, (TEXT("ERROR: failed to read NandLoader image.\r\n")));
        return FALSE;
    }
    if(memcmp((PVOID)dwImageStart, (PVOID)(EBOOT_FCACHE_START + 0x00100000), dwImageSize) != 0)
        OALMSG(OAL_INFO, (TEXT("ERROR: NandLoader image compare failed.\r\n")));
    else
        OALMSG(OAL_INFO, (TEXT("INFO: NandLoader image compare passed.\r\n")));

    DisplayMem(dwImageStart, dwImageSize, 0x100);
#endif
    EdbgOutputDebugString("INFO: Programming NandLoader to NAND complete.\r\n");

    OALMSG(OAL_FUNC, (TEXT("WriteNandLoaderRegionToNand-\r\n")));
    return TRUE;
}

#ifdef DEBUG
//-----------------------------------------------------------------------------
//
//  FUNCTION:        GetBlockNumberInput
//
//  DESCRIPTION:    Loops to get a valid block number from user
//                    input. Breaks if user presses enter only.
//
//  PARAMETERS:        
//                    None
//                    
//  RETURNS:        
//                    -1 for no block number entered
//                    entered block number otherwise
//
//-----------------------------------------------------------------------------
static DWORD GetBlockNumberInput(void)
{
    DWORD dwBlock;
    CHAR number;
    BYTE nNumChar;

    dwBlock = 0;
    nNumChar= 0;
    while(1)
    {
        number = OEMReadDebugByte();
        if(number == OEM_DEBUG_READ_NODATA)
            continue;
        
        if(number == 0x08)
        {
            // backspace
            if(nNumChar > 0)
            {
                nNumChar--;
                OEMWriteDebugByte(number);
                OEMWriteDebugByte(0xFF);
                OEMWriteDebugByte(number);
                dwBlock /= 10;
            }
        }

        if(number >= '0' && number <= '9')
        {
            nNumChar++;
            OEMWriteDebugByte(number);
            dwBlock *= 10;
            dwBlock += number - '0';
        }

        if(number == '\n' || number == '\r')
        {
            if(dwBlock >= 0 && dwBlock < g_FlashInfo.dwNumBlocks)
                break;
            else
            {
                OALMSG(1, (TEXT("ERROR: Invalid block %d.\r\n"), dwBlock));
                dwBlock = 0;
                nNumChar = 0;
            }
        }
    }
    OALMSG(1, (TEXT("\r\n")));
    if(nNumChar == 0)
        return -1;
    else
        return dwBlock;
}

/*********************************************************************
 *
 *  FUNCTION:        DisplayMem
 *
 *  DESCRIPTION:    Display mem contents in hex
 *
 *  PARAMETERS:        
 *                    start - mem start
 *                    size - mem end
 *                    displaySize - size of mem to display at a go
 *                    
 *  RETURNS:        
 *                    None
 *
 ********************************************************************/
static void DisplayMem(UINT32 start, UINT32 size, UINT32 displaySize)
{
    UINT32 *pImage;
    UINT32 dwSize;
    BOOL bStopDisplay;
    char selection;

    pImage = (UINT32 *)start;
    bStopDisplay = FALSE;
    dwSize = 0;

    while(size > 0 && bStopDisplay == FALSE)
    {
        OALMSG(1, (TEXT("0x%08X: %08X %08X %08X %08X\r\n"), pImage,
            LE32(*pImage), LE32(*(pImage+1)), LE32(*(pImage+2)), LE32(*(pImage+3)) ));
        pImage += 4;
        dwSize += 4 * sizeof(DWORD);
        size -= 4 * sizeof(DWORD);

        if(dwSize >= displaySize && dwSize % displaySize == 0)
        {
            OALMSG(1, (TEXT("Press Enter to continue or 'b' to break.\r\n")));
            while(1)
            {
                selection = OEMReadDebugByte();
                if(selection == 0x0d || selection == 0x20)
                    break;
                if(selection == 'b' || selection == 'B')
                {
                    bStopDisplay = TRUE;
                    break;
                }
            };
        }
    }
}
#endif
//-----------------------------------------------------------------------------
// END OF FILE
//-----------------------------------------------------------------------------

⌨️ 快捷键说明

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