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

📄 nand.c

📁 Freescale ARM11系列CPU MX31的WINCE 5.0下的BSP
💻 C
📖 第 1 页 / 共 4 页
字号:
        EdbgOutputDebugString("WARNING: NAND device doesn't exist - unable to store image.\r\n");
        return(FALSE);
    }

    EdbgOutputDebugString("INFO: Prepare for writing DIO image to NAND.\r\n");

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

    // Make sure DIO image length does not exceed reserved NAND size
    if (dwLength > IMAGE_BOOT_DIOIMAGE_NAND_SIZE)
    {
        EdbgOutputDebugString("ERROR: DIO image size exceeds reserved NAND region (size = 0x%x)\r\n", dwLength);
        return(FALSE);
    }

    // Force all blocks in XLDR(128KB), EBOOT(256KB) and IPL(256KB) to be reserved
    startBlockID = 0;
    endBlockID = (IMAGE_BOOT_DIOIMAGE_NAND_OFFSET / g_flashInfo.dwBytesPerBlock) - 1;
    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;
        }

        // Set reserved status
        if ((FMD_GetBlockStatus(blockID) & BLOCK_STATUS_RESERVED) == 0)
        {
            EdbgOutputDebugString("INFO: Block [0x%x] not marked as bad or reserved. Force status to reserved.\r\n", blockID);

            if (!FMD_SetBlockStatus(blockID, BLOCK_STATUS_RESERVED))
            {
                EdbgOutputDebugString("ERROR: Block [0x%x] force reserved status failed.\r\n", blockID);
                return(FALSE);
            }
        }        
    }

    // Calculate the physical block range for the DIO image
    startBlockID = IMAGE_BOOT_DIOIMAGE_NAND_OFFSET / g_flashInfo.dwBytesPerBlock;
    endBlockID = startBlockID + (IMAGE_BOOT_DIOIMAGE_NAND_SIZE / g_flashInfo.dwBytesPerBlock);

    EdbgOutputDebugString("INFO: Erasing NAND flash blocks [0x%x - 0x%x].\r\n", startBlockID, endBlockID);
    
    // Erase range of NAND blocks reserved for DIO image
    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);
        }

        percentComplete = 100 * (blockID - startBlockID + 1) / (endBlockID - startBlockID);
        // If percentage complete has changed, show the progress
        if (lastPercentComplete != percentComplete)
        {
            lastPercentComplete = percentComplete;
            OEMWriteDebugByte('\r');
            EdbgOutputDebugString("INFO: Erase is %d%% complete.", percentComplete);
        }

    }

    EdbgOutputDebugString("\r\nINFO: Ready to write DIO image ... \r\n");
    
    return(TRUE);
}

//------------------------------------------------------------------------------
//
//  Function:  NANDContinueWriteBinDIO
//
//  N/A
//
//  Parameters:
//      None.
//
//  Returns:
//      TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NANDContinueWriteBinDIO(DWORD dwAddress, BYTE *pbData, DWORD dwSize)
{
    BOOL bOK;
    BLOCK_ID blockID;
    SECTOR_ADDR sectorAddr;
    SectorInfo *pSectorInfo;
    UINT32 blockSize, sectorSize;
    UINT32 dwCount;
    static UINT32 nTimes = 0, dwBadBlock = 0;

    // Check for NAND device availability
    //
    if (!g_bNandExist)
    {
        EdbgOutputDebugString("WARNING: NAND device doesn't exist - unable to store image.\r\n");
        return(FALSE);
    }

    // First we need to calculate position where to write
    sectorSize = g_flashInfo.wDataBytesPerSector + sizeof(SectorInfo);
    blockSize = g_flashInfo.wSectorsPerBlock * sectorSize;
    blockID = dwAddress / blockSize;
    sectorAddr = (dwAddress - blockID * blockSize) / sectorSize;

    // Shift block by DIO image region base
    blockID += (IMAGE_BOOT_DIOIMAGE_NAND_OFFSET / g_flashInfo.dwBytesPerBlock);

    // Skip the number of bad blocks
    blockID += dwBadBlock;

    // Write record
    dwCount = 0;
    while (dwCount < dwSize && blockID < g_flashInfo.dwNumBlocks) 
    {
        // Skip bad blocks
        if (FMD_GetBlockStatus(blockID) == BLOCK_STATUS_BAD)
        {
            EdbgOutputDebugString("INFO: Found bad NAND flash block [0x%x].\r\n", blockID);
            blockID++;
            dwBadBlock++;
            continue;
        }
  
        // Write sectors
        bOK = TRUE;
        while (sectorAddr < g_flashInfo.wSectorsPerBlock && dwCount < dwSize) 
        {
            // First we have to check for empty sectors
            pSectorInfo = (SectorInfo *)(pbData + dwCount + g_flashInfo.wDataBytesPerSector);

            // Don't write empty sector
            if (IsSectorEmpty(pbData + dwCount, g_flashInfo.wDataBytesPerSector, pSectorInfo))
            {
                // EdbgOutputDebugString("INFO: Skipping empty sector [0x%x].\r\n", sectorAddr);
                
                // Move to next sector
                dwCount += sectorSize;
                sectorAddr++;
                continue;
            }

            // Clear reserved flag if set
            pSectorInfo->bOEMReserved |= OEM_BLOCK_RESERVED;

            // Never ever write sector with bad block
            if (pSectorInfo->bBadBlock != 0xFF)
            {
                EdbgOutputDebugString("ERROR: Incorrect or corrupted DIO BIN file - bad block flag set.\r\n");
                return(FALSE);
            }

            // Write sector
            if (!(bOK = FMD_WriteSector(blockID * g_flashInfo.wSectorsPerBlock + sectorAddr, 
                pbData + dwCount, pSectorInfo, 1)))
            {
                EdbgOutputDebugString("ERROR: Writing sector [0x%x] failed.\r\n", sectorAddr);
                break;
            }

            // Move to next sector
            dwCount += sectorSize;
            sectorAddr++;
        }

        // When sector write failed, mark block as bad and move back
        if (!bOK) 
        {
            EdbgOutputDebugString("WARN: Block [0x%x] / sector [0x%x] write failed, mark block as bad.\r\n", blockID, sectorAddr);

            // First move back
            dwCount -= sectorAddr * sectorSize;
            // Mark block as bad
            FMD_SetBlockStatus(blockID, BLOCK_STATUS_BAD);
            blockID++;
            continue;
        }

        // We are done with block
        sectorAddr = 0;
        blockID++;
    }

    // Progress
    OEMWriteDebugByte('\r');
    switch (nTimes++ % 4)
    {
        case 0:
            OEMWriteDebugByte('\\');
            break;
                
        case 1:
            OEMWriteDebugByte('|');
            break;
                
        case 2:
            OEMWriteDebugByte('/');
            break;

        case 3:
            OEMWriteDebugByte('-');
    }

    // Before we leave erase buffer
    memset(pbData, 0xFF, dwSize);

    // If we wrote all, we are succesfull
    return (dwCount >= dwSize);
}

//------------------------------------------------------------------------------
//
//  Function:  NANDFinishWriteBinDIO
//
//  N/A
//
//  Parameters:
//      None.
//
//  Returns:
//      TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NANDFinishWriteBinDIO()
{
    if (!g_bNandExist)
    {
        EdbgOutputDebugString("\r\nINFO: No NAND present!\r\n");
        return(FALSE);
    }
    
    // Nothing to do...
    EdbgOutputDebugString("\r\nINFO: Update of DIO image completed successfully.\r\n");

    return TRUE;
}

//------------------------------------------------------------------------------
//
//  Function:  NANDLoadIPL
//
//  N/A
//
//  Parameters:
//      None.
//
//  Returns:
//      TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NANDLoadIPL(VOID)
{
    FlashInfo flashInfo;
    LPBYTE pSectorBuf;
    SectorInfo sectorInfo;
    BLOCK_ID blockID, startBlockID, endBlockID;
    SECTOR_ADDR sectorAddr, startSectorAddr, endSectorAddr;

    // Check for NAND device availability
    //
    if (!g_bNandExist)
    {
        EdbgOutputDebugString("WARNING: NAND device doesn't exist - unable to read image.\r\n");
        return(FALSE);
    }

    EdbgOutputDebugString("INFO: Reading IPL image from NAND (please wait)...\r\n");

    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_IPLIMAGE_NAND_OFFSET / flashInfo.dwBytesPerBlock;
    endBlockID = startBlockID + (IMAGE_BOOT_IPLIMAGE_NAND_SIZE / flashInfo.dwBytesPerBlock);
    
    // Set image load address
    pSectorBuf = (LPBYTE) OALPAtoUA(IMAGE_BOOT_IPLIMAGE_RAM_START);

    EdbgOutputDebugString("INFO: Copying IPL image to RAM address 0x%x\r\n", pSectorBuf);
    
    // Copy IPL 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 IPL.\r\n");
                return(FALSE);
            }

            pSectorBuf += flashInfo.wDataBytesPerSector;
        }
    }

    EdbgOutputDebugString("INFO: Copy of IPL completed successfully.\r\n");

    return(TRUE);
}


//-----------------------------------------------------------------------------
//
//  Function:  NANDLoadNK
//
//  This function loads an OS image from NAND flash memory into RAM for
//  execution.
//
//  Parameters:
//      None.     
//
//  Returns:
//      TRUE indicates success. FALSE indicates failure.
//
//-----------------------------------------------------------------------------
BOOL NANDLoadNK(VOID)
{
    FlashInfo flashInfo;
    LPBYTE pSectorBuf;
    SectorInfo sectorInfo;
    BLOCK_ID blockID, startBlockID, endBlockID;
    SECTOR_ADDR sectorAddr, startSectorAddr, endSectorAddr;
    UINT32 percentComplete, lastPercentComplete;

    // Check for NAND device availability
    //
    if (!g_bNandExist)
    {
        EdbgOutputDebugString("WARNING: NAND device doesn't exist - unable to read image.\r\n");
        return(FALSE);
    }

    EdbgOutputDebugString("INFO: Reading NK image to NAND (please wait)...\r\n");

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

⌨️ 快捷键说明

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