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

📄 nand.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 5 页
字号:
            OALMSG(OAL_INFO, (TEXT("INFO: Successfully formatted NAND.\r\n")));
    
        OALMSG(OAL_INFO, (TEXT("INFO: Creating new BinFS partition.\r\n")));
        hPart = BP_OpenPartition(NEXT_FREE_LOC, dwNumSectors, 
                                PART_BINFS, TRUE, PART_OPEN_ALWAYS);

        if(hPart == INVALID_HANDLE_VALUE)
        {
            OALMSG(OAL_ERROR, (TEXT("ERROR: Cannot create BinFS partition!\r\n")));
            return FALSE;
        }
        else
            OALMSG(OAL_INFO, (TEXT("INFO: Successfully created BinFS partition.\r\n")));
        }
    else
        OALMSG(OAL_INFO, (TEXT("INFO: Successfully opened BinFS partition.\r\n")));
#else
    hPart = BP_OpenPartition(NEXT_FREE_LOC, dwNumSectors, 
                            PART_BINFS, TRUE, PART_OPEN_ALWAYS);
    if(hPart == INVALID_HANDLE_VALUE)
    {
            EdbgOutputDebugString("ERROR: Cannot create BinFS partition!\r\n");
            return FALSE;
    }
    else
        EdbgOutputDebugString("INFO: Successfully opened BinFS partition.\r\n");
#endif
    // Check partition size
    pPartEntry = BP_GetPartitionInfo(hPart);
    if(!pPartEntry)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: Cannot get BINFS partition info.\r\n")));
        return FALSE;
    }
    if(pPartEntry->Part_TotalSectors < dwNumSectors)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: Existing BINFS partition too small to store image. Please perform a low level format first!\r\n")));
        return FALSE;
    }
    else
        OALMSG(OAL_INFO, (TEXT("INFO: Existing partition size: 0x%X!\r\n"), pPartEntry->Part_TotalSectors * g_FlashInfo.wDataBytesPerSector));

    OALMSG(OAL_INFO, (TEXT("INFO: Writing OS RAM image to flash partition:\r\n")));

    // Create/open a bootsection partition to nand params.
    hBootPart = BP_OpenPartition(NEXT_FREE_LOC, 
                                NAND_IMAGE_NUM_SECTOR(sizeof(EBOOT_NANDCFG), g_FlashInfo.wDataBytesPerSector), 
                                PART_BOOTSECTION, FALSE, PART_OPEN_ALWAYS);
    if(hBootPart == INVALID_HANDLE_VALUE)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: failed to create/open BOOTSECTION partition.\r\n")));
        return FALSE;
    }
    else
    {
        nandParams.ConfigMagicNumber = EbootCFGMagicNumber;
    }
    
    // Are there multiple BIN files in RAM (we may just be updating 
    // one in a multi-BIN solution)?
    for(nCount = 0; nCount < g_BINRegionInfo.dwNumRegions; nCount++)
    {
        DWORD dwRegionStart  = g_BINRegionInfo.Region[nCount].dwRegionStart;
        DWORD dwRegionLength = g_BINRegionInfo.Region[nCount].dwRegionLength;
        DWORD dwImageOffset;

        if(OEMIsFlashAddr(dwRegionStart))
        {
            EdbgOutputDebugString("WARNING: Image built for FLASH. Skipping NAND program.\r\n");
            break;
        }
        
        // Get offset of region into image.
        if (xip_chain_addr == dwRegionStart)
            dwImageOffset = nandParams.dwChainOffset;
        else
            dwImageOffset = dwRegionStart - OS_RAM_IMAGE_START;
            
        OALMSG(OAL_FUNC, (TEXT("dwRegionStart: %X dwImageOffset:%X\r\n"), 
                    dwRegionStart, dwImageOffset));

        // Set the offset into the BINFS partition and write the image.
        if(!BP_SetDataPointer(hPart, dwImageOffset))
        {
            OALMSG(OAL_ERROR, (TEXT("ERROR: failed to set data pointer in BINFS partition (address=0x%x).\r\n"), dwImageOffset));
            return FALSE;
        }

        if(!BP_WriteData(hPart, (LPBYTE)dwRegionStart, dwRegionLength))
        {
            OALMSG(OAL_ERROR, (TEXT("ERROR: failed to write BINFS data (start=0x%x, length=0x%x).\r\n"), dwRegionStart, dwRegionLength));
            return FALSE;
        }
    
        // Check if region is kernel region by checking if launch address 
        // is in current region.
        // If so, save the region's information in the bootloader 
        // settings partition for use later when retrieving the region.
        if(pBootCfg->LaunchAddress >= dwRegionStart &&
            pBootCfg->LaunchAddress < (dwRegionStart + dwRegionLength))
        {
            nandParams.dwLaunchAddr = pBootCfg->LaunchAddress; 
            nandParams.dwRegionStart = dwRegionStart;
            nandParams.dwImageOffset = dwImageOffset;
        }
    }

    // Set the length to be total length less the lenght of the XIP Chain
    // as that gets read out separately
    nandParams.dwRegionLength= dwPartitionLength - nandParams.dwChainLength;
    
    OALMSG(OAL_FUNC, (TEXT("launch (0x%x), start (0x%x), len (0x%x), offset (0x%x)\n"),
     nandParams.dwLaunchAddr, nandParams.dwRegionStart, nandParams.dwRegionLength, nandParams.dwImageOffset));

    // Store Boot partition
    if(!BP_WriteData(hBootPart, (LPBYTE)&nandParams, sizeof(EBOOT_NANDCFG)))
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: failed to write BOOTSECTION data\r\n")));
        return FALSE;
    }

    // Create an extended partition to use rest of flash to mount a filesystem.
    hPart = BP_OpenPartition(NEXT_FREE_LOC, USE_REMAINING_SPACE, 
                        PART_EXTENDED, TRUE, PART_OPEN_ALWAYS);
    if(hPart == INVALID_HANDLE_VALUE)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: failed to create/open extended partition.\r\n")));
        return FALSE;
    }
    OALMSG(OAL_INFO, (TEXT("INFO: Programming OS to NAND complete.\r\n")));

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

//-----------------------------------------------------------------------------
//
//  FUNCTION:        WriteEBootRegionToNand
//
//  DESCRIPTION:    Writes EBoot bin region to NAND. 
//                    Note: This assumes that the blocks to be occupied
//                          by EBOOT is valid and good. 
//
//  PARAMETERS:        
//                    pBootCfg - Ptr to EBOOT configuration structure.
//                                Ignored.
//                    
//  RETURNS:        TRUE for success. FALSE for failure.
//
//-----------------------------------------------------------------------------
static BOOL WriteEBootRegionToNand(BOOT_CFG *pBootCfg)
{
    extern MultiBINInfo g_BINRegionInfo;
    DWORD dwRegionStart  = g_BINRegionInfo.Region[0].dwRegionStart;
    DWORD dwRegionLength = g_BINRegionInfo.Region[0].dwRegionLength;
    DWORD dwBlockStatus;
    DWORD dwStartSectorAddr;
    DWORD nSectors;
    DWORD dwNumSectors;
    DWORD dwImageStart;
    DWORD dwBlock;
    
    OALMSG(OAL_FUNC, (TEXT("WriteEBootRegionToNand+\r\n")));
    if(g_fNandExists != TRUE)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: NAND device doesn't exist - unable to write image.\r\n")));
        return FALSE;
    }

    if(g_BINRegionInfo.dwNumRegions > 1)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: Multi BIN regions(%d) in EBoot image unsupported. Skipping NAND program.\r\n"), g_BINRegionInfo.dwNumRegions));
        return FALSE;
    }

    if(OEMIsFlashAddr(dwRegionStart))
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: Image built for FLASH(%X). Skipping NAND program.\r\n"), dwRegionStart));
        return FALSE;
    }

    if(dwRegionLength > NAND_EBOOT_IMAGE_SIZE)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: EBOOT Image size(0x%X) greater than reserved. Skipping NAND program.\r\n"), dwRegionLength));
        return FALSE;
    }

    OALMSG(OAL_INFO, (TEXT("INFO: Writing EBOOT image to NAND:\r\n")));
    dwImageStart = (DWORD)OEMMapMemAddr(dwRegionStart, dwRegionStart);
    dwNumSectors = NAND_IMAGE_NUM_SECTOR(dwRegionLength, g_FlashInfo.wDataBytesPerSector);
    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: WriteNandLoade

⌨️ 快捷键说明

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