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

📄 nand.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: Non ROM_SIGNATURE! start:%X length:%X offset:%X\r\n"),
                    dwRegionStart, dwRegionLength, ROM_SIGNATURE_OFFSET));
        return NULL;
    }

    // A pointer to the ROMHDR structure lives just past the ROM_SIGNATURE (which is a longword value).  Note that
    // this pointer is remapped since it might be a flash address (image destined for flash), but is actually cached
    // in RAM.
    //
    dwCacheAddress = *(LPDWORD) OEMMapMemAddr (dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET + sizeof(ULONG));
    pROMHeader     = (ROMHDR *) OEMMapMemAddr (dwRegionStart, dwCacheAddress);

    // Make sure sure are some modules in the table of contents.
    //
    if((dwNumModules = pROMHeader->nummods) == 0)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: No modules in ROM header!\r\n")));
        return NULL;
    }

    // Locate the table of contents and search for the kernel executable and the TOC immediately follows the ROMHDR.
    //
    pTOC = (TOCentry *)(pROMHeader + 1);

    while(dwNumModules--) {
        LPBYTE pFileName = OEMMapMemAddr(dwRegionStart, (DWORD)pTOC->lpszFileName);
        if (!strcmp((const char *)pFileName, "nk.exe")) {
            OALMSG(OAL_INFO, (TEXT("INFO: Kernel region found.\r\n")));
            return ((PVOID)(pROMHeader->pExtensions));
        }
        ++pTOC;
    }

    OALMSG(OAL_FUNC, (TEXT("GetKernelExtPointer-\r\n")));
    return NULL;
}

//-----------------------------------------------------------------------------**
//
//  FUNCTION:        GetNandLoaderFilePointer
//
//  DESCRIPTION:    Used to locate the nand loader binary file area.
//
//  PARAMETERS:        
//            dwRegionStart - start of region
//            dwRegionLength - size of region
//
//  RETURNS:        
//             Pointer to kernel's extension area. NULL if failure.
//-----------------------------------------------------------------------------
static PVOID GetNandLoaderFilePointer(DWORD dwRegionStart, DWORD dwRegionLength)
{
    DWORD dwCacheAddress = 0;
    ROMHDR *pROMHeader;
    DWORD dwNumFiles = 0;
    TOCentry *pTOC;
    FILESentry *pFILES;

    OALMSG(OAL_FUNC, (TEXT("GetNandLoaderFilePointer+\r\n")));

    if (dwRegionStart == 0 || dwRegionLength == 0)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: dwRegionStart:%X dwRegionLength:%X\r\n"),
                    dwRegionStart, dwRegionLength));
        return(NULL);
    }

    if (*(LPDWORD)OEMMapMemAddr(dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET) != ROM_SIGNATURE)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: Non ROM_SIGNATURE! start:%X length:%X offset:%X\r\n"),
                    dwRegionStart, dwRegionLength, ROM_SIGNATURE_OFFSET));
        return NULL;
    }

    // A pointer to the ROMHDR structure lives just past the ROM_SIGNATURE (which is a longword value).  Note that
    // this pointer is remapped since it might be a flash address (image destined for flash), but is actually cached
    // in RAM.
    //
    dwCacheAddress = *(LPDWORD) OEMMapMemAddr (dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET + sizeof(ULONG));
    pROMHeader     = (ROMHDR *) OEMMapMemAddr (dwRegionStart, dwCacheAddress);

    OALMSG(OAL_FUNC, (TEXT("dwCacheAddress:%X dwRegionStart:%X :%X\r\n"), dwCacheAddress, dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET + sizeof(ULONG)));
    OALMSG(OAL_FUNC, (TEXT("pROMHeader:%X\r\n"), pROMHeader));

    OALMSG(OAL_FUNC, (TEXT("\n")));
    OALMSG(OAL_FUNC, (TEXT("ROMHDR ----------------------------------------\r\n")));
    OALMSG(OAL_FUNC, (TEXT("    DLL First           : 0x%X  \r\n"), pROMHeader->dllfirst));
    OALMSG(OAL_FUNC, (TEXT("    DLL Last            : 0x%X  \r\n"), pROMHeader->dlllast));
    OALMSG(OAL_FUNC, (TEXT("    Physical First      : 0x%X  \r\n"), pROMHeader->physfirst));
    OALMSG(OAL_FUNC, (TEXT("    Physical Last       : 0x%X  \r\n"), pROMHeader->physlast));
    OALMSG(OAL_FUNC, (TEXT("    RAM Start           : 0x%X  \r\n"), pROMHeader->ulRAMStart));
    OALMSG(OAL_FUNC, (TEXT("    RAM Free            : 0x%X  \r\n"), pROMHeader->ulRAMFree));
    OALMSG(OAL_FUNC, (TEXT("    RAM End             : 0x%X  \r\n"), pROMHeader->ulRAMEnd));
    OALMSG(OAL_FUNC, (TEXT("    Kernel flags        : 0x%X  \r\n"), pROMHeader->ulKernelFlags));
    OALMSG(OAL_FUNC, (TEXT("    Prof Symbol Offset  : 0x%X  \r\n"), pROMHeader->ulProfileOffset));
    OALMSG(OAL_FUNC, (TEXT("    Num Copy Entries    : %d    \r\n"), pROMHeader->ulCopyEntries));
    OALMSG(OAL_FUNC, (TEXT("    Copy Entries Offset : 0x%X  \r\n"), pROMHeader->ulCopyOffset));
    OALMSG(OAL_FUNC, (TEXT("    Num Modules         : %d    \r\n"), pROMHeader->nummods));
    OALMSG(OAL_FUNC, (TEXT("    Num Files           : %d    \r\n"), pROMHeader->numfiles));

    // Make sure sure are some modules in the table of contents.
    //
    if(pROMHeader->nummods == 0)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: No modules in ROM header!\r\n")));
        return NULL;
    }

    // Make sure sure are some files in the table of contents.
    //
    if((dwNumFiles = pROMHeader->numfiles) == 0)
    {
        OALMSG(OAL_ERROR, (TEXT("ERROR: No files in ROM header! %d\r\n"), dwNumFiles));
        return NULL;
    }

    // Locate the table of contents and search for the nandloader binary.
    //
    pTOC = (TOCentry *)(pROMHeader + 1);
    pFILES = (FILESentry *)(pTOC + pROMHeader->nummods);

    while(dwNumFiles--) {
        LPBYTE pFileName = OEMMapMemAddr(dwRegionStart, (DWORD)pFILES->lpszFileName);
        switch(g_FlashWidth)
        {
            case 8:
                if (!strcmp((const char *)pFileName, "nandloader_8bit.nb0")) {
                    OALMSG(OAL_FUNC, (TEXT("Nandloader 8bit file found.\r\n")));
                    return ((PVOID)(pFILES));
                }
                break;
            case 16:               
                if (!strcmp((const char *)pFileName, "nandloader_16bit.nb0")) {
                    OALMSG(OAL_FUNC, (TEXT("Nandloader 16bit file found.\r\n")));
                    return ((PVOID)(pFILES));
                }
                break;
            default:
                return NULL;
        }
        ++pFILES;
    }

    OALMSG(OAL_FUNC, (TEXT("GetNandLoaderFilePointer-\r\n")));
    return NULL;
}

//-----------------------------------------------------------------------------
//
//  FUNCTION:        GetRequiredNumBlocks
//
//  DESCRIPTION:    Gets the number of blocks required for EBOOT
//                    region including bad blocks in region. Also checks
//                    for a valid start block of the region.
//
//  PARAMETERS:        
//                    pBootCfg - Ptr to EBOOT configuration structure.
//                                Ignored.
//                    
//  RETURNS:        TRUE for success. FALSE for failure.
//
//-----------------------------------------------------------------------------
static DWORD FindFirstGoodBlock(DWORD dwStartBlock)
{
    DWORD dwBlockStatus;
    DWORD dwBlock;

    OALMSG(OAL_FUNC, (TEXT("FindFirstGoodBlock+\r\n")));
    for(dwBlock = dwStartBlock; dwBlock < g_FlashInfo.dwNumBlocks; dwBlock++)
    {
        dwBlockStatus = FMD_GetBlockStatus(dwBlock);
        if(!(dwBlockStatus & (BLOCK_STATUS_UNKNOWN | BLOCK_STATUS_BAD)))
            break;
    }
    
    OALMSG(OAL_FUNC, (TEXT("FindFirstGoodBlock-: dwBlock: %d\r\n"), dwBlock));
    return dwBlock;
}

//-----------------------------------------------------------------------------
//
//  FUNCTION:        WriteRegionsToNand
//
//  DESCRIPTION:    Writes bin regions to NAND.
//
//  PARAMETERS:        
//                    pBootCfg - Ptr to EBOOT configuration structure
//                    
//  RETURNS:        TRUE for success. FALSE for failure.
//
//-----------------------------------------------------------------------------
static BOOL WriteOSRegionsToNand(BOOT_CFG *pBootCfg)
{
    extern MultiBINInfo g_BINRegionInfo;
    EBOOT_NANDCFG nandParams;
    PXIPCHAIN_SUMMARY pChainInfo = NULL;
    PPARTENTRY pPartEntry;
    HANDLE hPart;
    HANDLE hBootPart;
    DWORD dwNumExts;
    DWORD dwPartitionLength = 0;
    DWORD dwNumSectors = 0;
    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

⌨️ 快捷键说明

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