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

📄 flash.c

📁 Windows CE 6.0 BSP for the Beagle Board.
💻 C
📖 第 1 页 / 共 3 页
字号:
    ));

    // Write EBOOT image
    count = 0;
    while (count < IMAGE_EBOOT_CODE_SIZE && block < flashInfo.dwNumBlocks) {
        if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
            block++;
            OALMSG(OAL_INFO, (L"$"));
            continue;
        }

        // Erase block
        if (!EraseBlock(block)) {
            FMD_SetBlockStatus(block, BLOCK_STATUS_BAD);
            block++;
            OALMSG(OAL_INFO, (L"#"));
            continue;
        }

        // Now write sectors
        ix = 0;
        while (
            ix < flashInfo.wSectorsPerBlock && count < IMAGE_EBOOT_CODE_SIZE
        ) {
            // Prepare sector info
            memset(&sectorInfo, 0xFF, sizeof(sectorInfo));
            sectorInfo.bOEMReserved &= ~(OEM_BLOCK_READONLY|OEM_BLOCK_RESERVED);
            sectorInfo.dwReserved1 = 0;
            sectorInfo.wReserved2 = 0;

            // Write sector
            ok = WriteSector(
                block * flashInfo.wSectorsPerBlock + ix, pData + count,
                &sectorInfo
            );

            // When write fail, break sector write loop
            if (!ok) break;

            // Move to next sector
            count += sectorSize;
            ix++;
            OALMSG(OAL_INFO, (L"."));
        }

        // When sector write failed, mark block as bad and move back
        if (!ok) {
            // First move back
            count -= ix * flashInfo.wDataBytesPerSector;
            // Mark block as bad
            FMD_SetBlockStatus(block, BLOCK_STATUS_BAD);
            block++;
            OALMSG(OAL_INFO, (L"%"));
            continue;
        }

        // We are done with block
        block++;
    }

    OALMSG(OAL_INFO, (L"\r\nOEMWriteFlash: EBOOT written\r\n"));

    // Done
    rc = (count >= size);

cleanUp:
    if (hFMD != NULL) FMD_Deinit(hFMD);
    return rc;

}

//------------------------------------------------------------------------------

BOOL WriteFlashIPL(UINT32 address, UINT32 size)
{
    BOOL rc = FALSE, ok = FALSE;
    HANDLE hFMD = NULL;
    ROMHDR *pTOC;
    FlashInfo flashInfo;
    UINT32 blockSize, sectorSize;
    SectorInfo sectorInfo;
    BLOCK_ID block;
    UINT32 *pInfo, ix, count;
    UINT8 *pData;

    OALMSG(OAL_INFO, (L"OEMWriteFlash: Writing IPL image to flash\r\n"));

    // Check if image fit
    if (size > IMAGE_EBOOT_CODE_SIZE) {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"EBOOT image too big (size 0x%08x, maximal size 0x%08x)\r\n",
            size, IMAGE_EBOOT_CODE_SIZE
        ));
    }

    // Open FMD to access NAND
    hFMD = FMD_Init(NULL, NULL, NULL);
    if (hFMD == NULL) {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"FMD_Init call failed!\r\n"
        ));
        goto cleanUp;
    }

    // Get flash info
    if (!FMD_GetInfo(&flashInfo)) {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"FMD_GetInfo call failed!\r\n"
        ));
        goto cleanUp;
    }
    blockSize = flashInfo.dwBytesPerBlock;
    sectorSize = flashInfo.wDataBytesPerSector;

    OALMSG(OAL_INFO, (L"OEMWriteFlash: "
        L"Flash has %d blocks, %d bytes/block, %d sectors/block\r\n",
        flashInfo.dwNumBlocks, flashInfo.dwBytesPerBlock,
        flashInfo.wSectorsPerBlock
    ));

    // Get data location
    pData = OEMMapMemAddr(address, address);

    // Verify that we get CE image.
    pInfo = (UINT32*)(pData + ROM_SIGNATURE_OFFSET);
    if (*pInfo++ != ROM_SIGNATURE) {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"Image Signature not found\r\n"
        ));
        goto cleanUp;
    }
    pInfo++;

    // We are on correct location....
    pTOC = (ROMHDR*)((UINT32)*pInfo + IMAGE_WINCE_CODE_PA);

    // Let see
    DumpTOC(pTOC);

    // Fill unused space with 0xFF
    if (size < IMAGE_EBOOT_CODE_SIZE) memset(
        pData + size, 0xFF, IMAGE_EBOOT_CODE_SIZE - size
    );

    // Skip OMAP2420 XLDR and EBOOT image
    block = 0;
    count = 0;
    while (
        count < IMAGE_XLDR_CODE_SIZE + IMAGE_EBOOT_CODE_SIZE &&
        block < flashInfo.dwNumBlocks
    ) {
        if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
            block++;
            OALMSG(OAL_INFO, (L"$"));
            continue;
        }
        count += blockSize;
        block++;
    }

    OALMSG(OAL_INFO, (L"OEMWriteFlash: "
        L"IPL image starts at block %d\r\n",  block
    ));

    // Write EBOOT image
    count = 0;
    while (count < IMAGE_EBOOT_CODE_SIZE && block < flashInfo.dwNumBlocks) {
        if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
            block++;
            OALMSG(OAL_INFO, (L"$"));
            continue;
        }

        // When erase failed, mark block as bad and skip it
        if (!EraseBlock(block)) {
            FMD_SetBlockStatus(block, BLOCK_STATUS_BAD);
            block++;
            OALMSG(OAL_INFO, (L"#"));
            continue;
        }

        // Now write sectors
        ix = 0;
        while (
            ix < flashInfo.wSectorsPerBlock && count < IMAGE_EBOOT_CODE_SIZE
        ) {
            // Prepare sector info
            memset(&sectorInfo, 0xFF, sizeof(sectorInfo));
            sectorInfo.bOEMReserved &= ~(OEM_BLOCK_READONLY|OEM_BLOCK_RESERVED);
            sectorInfo.dwReserved1 = 0;
            sectorInfo.wReserved2 = 0;
            // Write sector
            ok = WriteSector(
                block * flashInfo.wSectorsPerBlock + ix, pData + count,
                &sectorInfo
            );

            // When write fail, break sector write loop
            if (!ok) break;

            // Move to next sector
            count += sectorSize;
            ix++;
            OALMSG(OAL_INFO, (L"."));
        }

        // When sector write failed, mark block as bad and move back
        if (!ok) {
            // First move back
            count -= ix * flashInfo.wDataBytesPerSector;
            // Mark block as bad
            FMD_SetBlockStatus(block, BLOCK_STATUS_BAD);
            block++;
            OALMSG(OAL_INFO, (L"%"));
            continue;
        }

        // We are done with block
        block++;
    }

    OALMSG(OAL_INFO, (L"\r\nOEMWriteFlash: IPL written\r\n"));

    // Done
    rc = (count >= size);

cleanUp:
    if (hFMD != NULL) FMD_Deinit(hFMD);
    return rc;

}

//------------------------------------------------------------------------------

BOOL WriteFlashNK(UINT32 address, UINT32 size)
{
    BOOL rc = FALSE;
    HANDLE hFMD;
    FlashInfo flashInfo;
    SectorInfo sectorInfo;
    BOOL ok = FALSE;
    BLOCK_ID block;
    ROMHDR *pTOC;
    UINT32 *pInfo, count, sector;
    UINT32 blockSize, sectorSize, sectorsPerBlock;
    UINT8 *pData;


    OALMSG(OAL_INFO, (L"OEMWriteFlash: Writing NK image to flash\r\n"));

    // We need to know sector/block size
    if ((hFMD = FMD_Init(NULL, NULL, NULL)) == NULL) {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"FMD_Init call failed\r\n"
        ));
        goto cleanUp;
    }

    // Get flash info
    if (!FMD_GetInfo(&flashInfo)) {
        OALMSG(OAL_ERROR, (L"ERROR: EBOOT!OEMWriteFlash: "
            L"FMD_GetInfo call failed!\r\n"
        ));
        FMD_Deinit(hFMD);
        goto cleanUp;
    }

    // We don't need access to FMD library
    FMD_Deinit(hFMD);

    OALMSG(OAL_INFO, (L"OEMWriteFlash: "
        L"Flash has %d blocks, %d bytes/block, %d sectors/block\r\n",
        flashInfo.dwNumBlocks, flashInfo.dwBytesPerBlock,
        flashInfo.wSectorsPerBlock
    ));

    // Make block & sector size ready
    blockSize = flashInfo.dwBytesPerBlock;
    sectorSize = flashInfo.wDataBytesPerSector;
    sectorsPerBlock = flashInfo.wSectorsPerBlock;

    // Get data location
    pData = OEMMapMemAddr(address, address);

    // Verify that we get CE image.
    pInfo = (UINT32*)(pData + ROM_SIGNATURE_OFFSET);
    if (*pInfo++ != ROM_SIGNATURE) {
        OALMSG(OAL_ERROR, (L"ERROR: OEMWriteFlash: "
            L"Image Signature not found\r\n"
        ));
        goto cleanUp;
    }
    pInfo++;

    // We are on correct location....
    pTOC = (ROMHDR*)((UINT32)*pInfo + IMAGE_WINCE_CODE_PA);

    // Let see
    DumpTOC(pTOC);

    // Skip reserved blocks
    block = 0;
    while (block < flashInfo.dwNumBlocks) {
        if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
            OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: "
                L"Skip bad block %d\r\n", block
            ));
            block++;
            continue;
        }
        if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_RESERVED) == 0) break;
        block++;
    }

    OALMSG(OAL_INFO, (L"OEMWriteFlash: "
        L"NK image starts at block %d\r\n",  block
    ));

    // Write image
    count = 0;
    while (count < size && block < flashInfo.dwNumBlocks) {

        // If block is bad, we have to offset it
        if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
            block++;
            OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: "
                L"Skip bad block %d\r\n", block
            ));
            continue;
        }

        // Erase block
        if (!EraseBlock(block)) {
            FMD_SetBlockStatus(block, BLOCK_STATUS_BAD);
            block++;
            OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: "
                L"Block %d erase failed, mark block as bad\r\n", block
            ));
            continue;
        }

        // Now write sectors
        sector = 0;
        while (sector < sectorsPerBlock && count < size) {

            // Prepare sector info
            memset(&sectorInfo, 0xFF, sizeof(sectorInfo));
            sectorInfo.dwReserved1 = 0;
            sectorInfo.wReserved2 = 0;

            // Write sector
            if (!(ok = WriteSector(
                block * sectorsPerBlock + sector, pData + count, &sectorInfo
            ))) break;

            // Move to next sector
            count += sectorSize;
            sector++;
        }

        // When sector write failed, mark block as bad and move back
        if (!ok) {
            OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: "
                L"Block %d sector %d write failed, mark block as bad\r\n", 
                block, sector
            ));
            // First move back
            count -= sector * flashInfo.wDataBytesPerSector;
            // Mark block as bad
            FMD_SetBlockStatus(block, BLOCK_STATUS_BAD);
        }

        // We are done with block
        block++;
    }

    // Erase rest of media
    while (block < flashInfo.dwNumBlocks) {

        // If block is bad, we have to offset it
        if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
            block++;
            OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: "
                L"Skip bad block %d\r\n", block
            ));
            continue;
        }

        // When erase failed, mark block as bad and skip it
        if (!EraseBlock(block)) {
            FMD_SetBlockStatus(block, BLOCK_STATUS_BAD);
            block++;
            OALMSG(OAL_WARN, (L"WARN: EBOOT!OEMWriteFlash: "
                L"Block %d erase failed, mark block as bad\r\n", block
            ));
            continue;
        }

        // Move to next block
        block++;
    }

    // Close FMD driver
    FMD_Deinit(hFMD);
    hFMD = NULL;

    OALMSG(OAL_INFO, (L"OEMWriteFlash: NK written\r\n"));

    // Change boot device to NAND
    g_bootCfg.bootDevLoc.IfcType = Internal;
    g_bootCfg.bootDevLoc.LogicalLoc = BSP_NAND_REGS_PA + 0x20;

    // Done
    rc = TRUE;

cleanUp:
    if (hFMD != NULL) FMD_Deinit(hFMD);
    return rc;
}
    
//------------------------------------------------------------------------------

BOOL WriteSector(SECTOR_ADDR sector, VOID *pBuffer, SectorInfo *pInfo)
{
    BOOL rc;
    UINT32 retry = 4;

    do {
        rc = FMD_WriteSector(sector, pBuffer, pInfo, 1);
    } while (!rc && --retry > 0);
    return rc;
}

//------------------------------------------------------------------------------

BOOL EraseBlock(BLOCK_ID block)
{
    BOOL rc;
    UINT32 retry = 4;

    // Erase block
    do {
        rc = FMD_EraseBlock(block);
    } while (!rc && --retry > 0);
    return rc;
}

//------------------------------------------------------------------------------

VOID DumpTOC(ROMHDR *pTOC)
{
    // Print out ROMHDR information
    OALMSG(OAL_INFO, (L"\r\n"));
    OALMSG(OAL_INFO, (L"ROMHDR (pTOC = 0x%08x) ---------------------\r\n", pTOC));
    OALMSG(OAL_INFO, (L"  DLL First           : 0x%08x\r\n", pTOC->dllfirst));
    OALMSG(OAL_INFO, (L"  DLL Last            : 0x%08x\r\n", pTOC->dlllast));
    OALMSG(OAL_INFO, (L"  Physical First      : 0x%08x\r\n", pTOC->physfirst));
    OALMSG(OAL_INFO, (L"  Physical Last       : 0x%08x\r\n", pTOC->physlast));
    OALMSG(OAL_INFO, (L"  Num Modules         : %10d\r\n",   pTOC->nummods));
    OALMSG(OAL_INFO, (L"  RAM Start           : 0x%08x\r\n", pTOC->ulRAMStart));
    OALMSG(OAL_INFO, (L"  RAM Free            : 0x%08x\r\n", pTOC->ulRAMFree));
    OALMSG(OAL_INFO, (L"  RAM End             : 0x%08x\r\n", pTOC->ulRAMEnd));
    OALMSG(OAL_INFO, (L"  Num Copy Entries    : %10d\r\n",   pTOC->ulCopyEntries));
    OALMSG(OAL_INFO, (L"  Copy Entries Offset : 0x%08x\r\n", pTOC->ulCopyOffset));
    OALMSG(OAL_INFO, (L"  Prof Symbol Length  : 0x%08x\r\n", pTOC->ulProfileLen));
    OALMSG(OAL_INFO, (L"  Prof Symbol Offset  : 0x%08x\r\n", pTOC->ulProfileOffset));
    OALMSG(OAL_INFO, (L"  Num Files           : %10d\r\n",   pTOC->numfiles));
    OALMSG(OAL_INFO, (L"  Kernel Flags        : 0x%08x\r\n", pTOC->ulKernelFlags));
    OALMSG(OAL_INFO, (L"  FileSys RAM Percent : 0x%08x\r\n", pTOC->ulFSRamPercent));
    OALMSG(OAL_INFO, (L"  Driver Glob Start   : 0x%08x\r\n", pTOC->ulDrivglobStart));
    OALMSG(OAL_INFO, (L"  Driver Glob Length  : 0x%08x\r\n", pTOC->ulDrivglobLen));
    OALMSG(OAL_INFO, (L"  CPU                 :     0x%04x\r\n", pTOC->usCPUType));
    OALMSG(OAL_INFO, (L"  MiscFlags           :     0x%04x\r\n", pTOC->usMiscFlags));
    OALMSG(OAL_INFO, (L"  Extensions          : 0x%08x\r\n", pTOC->pExtensions));
    OALMSG(OAL_INFO, (L"  Tracking Mem Start  : 0x%08x\r\n", pTOC->ulTrackingStart));
    OALMSG(OAL_INFO, (L"  Tracking Mem Length : 0x%08x\r\n", pTOC->ulTrackingLen));
    OALMSG(OAL_INFO, (L"------------------------------------------------\r\n"));
    OALMSG(OAL_INFO, (L"\r\n"));
}

//------------------------------------------------------------------------------

⌨️ 快捷键说明

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