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

📄 nand.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    BYTE nCount;
    UINT32 xip_chain_addr = 0;
    
    OALMSG(OAL_FUNC, (TEXT("WriteOSRegionsToNand+\r\n")));
    if(!pBootCfg)
    {
        OALMSG(OAL_ERROR, (TEXT("WriteOSRegionsToNand: Invalid input Parameter!\r\n")));
        return FALSE;
    }

    if(g_fNandExists != TRUE)
    {
        OALMSG(OAL_INFO, (TEXT("INFO: NAND device doesn't exist - unable to write image.\r\n")));
        return FALSE;
    }

    // Look in the kernel regions extension area for a multi-BIN
    // extension descriptor.  This region, if found, details the 
    // number, start, and size of each XIP region.
    for (nCount = 0, dwNumExts = 0 ; (nCount < g_BINRegionInfo.dwNumRegions) && !pChainInfo ; nCount++)
    {
        EXTENSION *pExt = NULL;
        // Does this region contain nk.exe and an extension pointer?
        if ((pExt = (EXTENSION *)GetKernelExtPointer(g_BINRegionInfo.Region[nCount].dwRegionStart, g_BINRegionInfo.Region[nCount].dwRegionLength)) != NULL)
        {
            // If there is an extension pointer region, walk it until the end.
            while (pExt)
            {
                DWORD dwBaseAddr = g_BINRegionInfo.Region[nCount].dwRegionStart;
                pExt = (EXTENSION *)OEMMapMemAddr(dwBaseAddr, (DWORD)pExt);
                if ((pExt->type == 0) && !strcmp(pExt->name, "chain information"))
                {
                    pChainInfo = (PXIPCHAIN_SUMMARY)OEMMapMemAddr(dwBaseAddr, (DWORD)pExt->pdata);
                    dwNumExts = (pExt->length / sizeof(XIPCHAIN_SUMMARY));
                    OALMSG(OAL_FUNC, (TEXT("Found chain information (pChainInfo=0x%x  Extensions=0x%x).\r\n"), (DWORD)pChainInfo, dwNumExts));
                    OALMSG(OAL_FUNC, (TEXT("pvAddr:0x%X dwMaxLength:0x%X usOrder:0x%x usFlags:0x%X\r\n"),
                            pChainInfo->pvAddr, pChainInfo->dwMaxLength, pChainInfo->usOrder, pChainInfo->usFlags));
                    // Store chain region info for booting use
                    nandParams.dwChainStart = (DWORD)pChainInfo->pvAddr;
                    nandParams.dwChainLength= pChainInfo->dwMaxLength;
                    nandParams.dwChainOffset = 0xffffffff;
                    
                    // Remember the chain idx
                    xip_chain_addr = nandParams.dwChainStart;
                    break;
                }
                
                pExt = (EXTENSION *)pExt->pNextExt;
            }
        }
    }

    // If we're downloading all the files in a multi-region image, 
    // first format the flash and write out logical sector numbers.
    if(pChainInfo && dwNumExts == g_BINRegionInfo.dwNumRegions)
    {
        // Skip the first entry - this is the chain file.
        for(nCount = 0, dwPartitionLength = 0; nCount < dwNumExts; nCount++)
        {
            // Handle both cases where the image is built for flash or for RAM.
            dwPartitionLength += (pChainInfo + nCount)->dwMaxLength;
            OALMSG(OAL_FUNC, (TEXT("dwPartitionLength:0x%X dwMaxLength:0x%X\r\n"),
                    dwPartitionLength, (pChainInfo + nCount)->dwMaxLength));
        }
        
        // Calculate the Chain offset - Locate after all the images
        nandParams.dwChainOffset = dwPartitionLength - nandParams.dwChainLength;
    }
    else
    {                        
        // If downloading a single image that contains the kernel 
        // then format the flash and write logical sector numbers.  
        // Note that we don't want to format flash when downloading 
        // a single image of a multi-image build.
        dwPartitionLength = g_BINRegionInfo.Region[0].dwRegionLength;
        nandParams.dwChainStart = 0;
        nandParams.dwChainLength= 0;
        nandParams.dwChainOffset = 0;
    }
    
    dwNumSectors = ((dwPartitionLength + g_FlashInfo.wDataBytesPerSector - 1) / g_FlashInfo.wDataBytesPerSector);
    
    OALMSG(OAL_FUNC, (TEXT("dwPartitionLength:%X dwNumSectors:%d\r\n"), 
            dwPartitionLength, dwNumSectors));

    // NOTE: Do not allow the partition manager to format the flash part if it can't 
    // find a valid MBR because default FORMAT_SKIP_RESERVED is not set by default.
    // This will result in OEM reserved blocks being erased.
    OALMSG(OAL_INFO, (TEXT("INFO: Creating/opening OS flash partition (this may take a few minutes if flash needs to be formatted).\r\n")));

    // Create/open a partition to store the image.
#if 1
    hPart = BP_OpenPartition(NEXT_FREE_LOC, dwNumSectors, 
                            PART_BINFS, TRUE, PART_OPEN_EXISTING);
    if(hPart == INVALID_HANDLE_VALUE)
    {
        DWORD dwCurMSec;
        BOOL bFormat = FALSE;
        BYTE selection;

        OALMSG(OAL_INFO, (TEXT("INFO: Cannot find existing BinFS partition.\r\n")));

        // No existing partition, do a low level format if user agrees.
        OALMSG(1, (TEXT("Press 'F' within 3 seconds to do a low level format.\r\n")));
        dwCurMSec = OEMEthGetSecs();
        while(OEMEthGetSecs() < (dwCurMSec + 3))
        {
            selection = OEMReadDebugByte();
            if((selection == 'f' || selection == 'F'))
            {
                bFormat = TRUE;
                break;
            }
        }

        if(bFormat == FALSE)
            return FALSE;

        OALMSG(OAL_INFO, (TEXT("INFO: Performing low level format on NAND...\r\n")));
        if(BP_LowLevelFormat(0, -1, FORMAT_SKIP_RESERVED) != TRUE)
        {
            OALMSG(OAL_ERROR, (TEXT("ERROR: Failed to low-level format NAND.\r\n")));
            return FALSE;
        }
        else
            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);

⌨️ 快捷键说明

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