📄 flash.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <windows.h>
#include <bsp.h>
#include "loader.h"
#include <fmd.h>
#include <s3c2440x.h>
#include "cfnand.h"
extern DWORD g_ImageType;
extern const PTOC g_pTOC;
extern DWORD g_dwTocEntry;
extern IPLmain(void);
static BOOL WriteFlashNK(UINT32 address, UINT32 size);
static BOOL WriteSector(SECTOR_ADDR sector, VOID *pBuffer, SectorInfo *pInfo);
static BOOL EraseBlock(BLOCK_ID block);
/*
@func BOOL | OEMIsFlashAddr | Tests whether the address provided resides in the Samsung's flash.
@rdesc TRUE = Specified address resides in flash, FALSE = Specified address doesn't reside in flash.
@comm
@xref
*/
BOOL OEMIsFlashAddr(DWORD dwAddr)
{
//EdbgOutputDebugString("OEMIsFlashAddr: 0x%x, %d\r\n", dwPhysStart, bRc);
return(TRUE);
}
/*
@func LPBYTE | OEMMapMemAddr | Remaps a specified address to a file cache location. The file cache is used as a temporary store for flash images before they're written to flash.
@rdesc Corresponding address within a file cache area.
@comm
@xref
*/
LPBYTE OEMMapMemAddr(DWORD dwImageStart, DWORD dwAddr)
{
if (g_ImageType & IMAGE_TYPE_DIO)
{
dwAddr = (FILE_CACHE_START + (dwAddr - NAND_ROM_IMAGE_BASE));
return (LPBYTE)dwAddr;
}
else
if (g_ImageType & IMAGE_TYPE_DIONB0)
{
dwAddr = (FILE_CACHE_START + (dwAddr - NAND_ROM_IMAGE_BASE));
return (LPBYTE)dwAddr;
}
else
if (g_ImageType & IMAGE_TYPE_STEPLDR)
{
dwAddr = (FILE_CACHE_START + (dwAddr - STEPLDR_RAM_IMAGE_BASE));
return (LPBYTE)dwAddr;
}
else
if (g_ImageType & IMAGE_TYPE_FLASHBIN)
{
dwAddr = (FILE_CACHE_START + (dwAddr - FLASHBIN_RAM_IMAGE_BASE));
return (LPBYTE)dwAddr;
}
else
if (g_ImageType & IMAGE_TYPE_UPLDR)
{
dwAddr = (FILE_CACHE_START + (dwAddr - UPLDR_RAM_IMAGE_BASE));
return (LPBYTE)dwAddr;
}
else
if (g_ImageType & IMAGE_TYPE_LOADER)
{
dwAddr = (FILE_CACHE_START + (dwAddr - EBOOT_RAM_IMAGE_BASE));
return (LPBYTE)dwAddr;
}
else
if (g_ImageType & IMAGE_TYPE_RAWBIN)
{
OALMSG(TRUE, (TEXT("OEMMapMemAddr 0x%x 0x%x\r\n"),dwAddr,(FILE_CACHE_START + dwAddr)));
dwAddr = FILE_CACHE_START + dwAddr;
return (LPBYTE)dwAddr;
}
return (LPBYTE)dwAddr;
}
//------------------------------------------------------------------------------
//
// Function: BLFlashDownload
//
// This function download image from flash memory to RAM.
//
UINT32 BLFlashDownload()
{
UINT32 rc = BL_ERROR;
IPLmain(); rc=BL_JUMP;
// rc = ReadFlashNK();
// rc = ReadFlashIPL();
return rc;
}
//------------------------------------------------------------------------------
static UINT32 ReadFlashIPL()
{
UINT32 rc = BL_ERROR;
HANDLE hFMD = NULL;
FlashInfo flashInfo;
UINT32 offset;
SectorInfo sectorInfo;
SECTOR_ADDR sector;
BLOCK_ID block;
UINT8 *pImage;
UINT32 *pInfo;
// Check if there is a valid image
OALMSG(OAL_INFO, (L"\r\nLoad IPL Image from flash memory\r\n"));
// Open FMD to access NAND
hFMD = FMD_Init(NULL, NULL, NULL);
if (hFMD == NULL) {
OALMSG(OAL_ERROR, (L"ERROR: BLFlashDownload: "
L"FMD_Init call failed\r\n"
));
goto cleanUp;
}
// Get flash info
if (!FMD_GetInfo(&flashInfo)) {
OALMSG(OAL_ERROR, (L"ERROR: BLFlashDownload: "
L"FMD_GetInfo call failed\r\n"
));
goto cleanUp;
}
// Start from NAND start
block = 0;
sector = 8;
offset = 0;
// Set address where to place image
pImage = (UINT8*)(IMAGE_IPL_ADDR_VA);
// Read image to memory
while (offset < IMAGE_IPL_SIZE && block < flashInfo.dwNumBlocks) {
// Read sectors in block
while ( offset < IMAGE_IPL_SIZE ) {
// When block read fail, there isn't what we can do more
if (!FMD_ReadSector(sector, pImage, §orInfo, 1)) {
OALMSG(OAL_ERROR, (L"\r\nERROR: BLFlashDownload: "
L"Failed read sector %d from flash\r\n", sector
));
goto cleanUp;
}
// Move to next sector
sector++;
pImage += flashInfo.wDataBytesPerSector;
offset += flashInfo.wDataBytesPerSector;
// OALMSG(OAL_INFO, (L"."));
}
// Move to next block
block++;
}
OALMSG(OAL_INFO, (L"\r\n"));
// Check if IPL is image and dump its content
pInfo = (UINT32*)(IMAGE_IPL_ADDR_VA + ROM_SIGNATURE_OFFSET);
if (*pInfo != ROM_SIGNATURE) {
OALMSG(OAL_ERROR, (L"ERROR: BLFlashDownload: "
L"IPL image doesn't have ROM signature at 0x%08x\r\n", pInfo
));
goto cleanUp;
}
g_pTOC->id[g_dwTocEntry].dwJumpAddress = IMAGE_IPL_ADDR_VA;
rc = BL_JUMP;
cleanUp:
return rc;
}
//------------------------------------------------------------------------------
static UINT32 ReadFlashNK()
{
UINT32 rc = BL_ERROR;
HANDLE hFMD = NULL;
FlashInfo flashInfo;
ROMHDR *pTOC;
UINT32 offset, size, toc;
UINT32 blockSize, sectorSize, sectorsPerBlock;
SectorInfo sectorInfo;
SECTOR_ADDR sector;
BLOCK_ID block;
UINT8 *pImage;
// Check if there is a valid image
OALMSG(OAL_INFO, (L"\r\nLoad NK image from flash memory\r\n"));
// Open FMD to access NAND
hFMD = FMD_Init(NULL, NULL, NULL);
if (hFMD == NULL) {
OALMSG(OAL_ERROR, (L"ERROR: BLFlashDownload: "
L"FMD_Init call failed\r\n"
));
goto cleanUp;
}
// Get flash info
if (!FMD_GetInfo(&flashInfo)) {
OALMSG(OAL_ERROR, (L"ERROR: BLFlashDownload: "
L"FMD_GetInfo call failed\r\n"
));
goto cleanUp;
}
// Make block & sector size ready
blockSize = flashInfo.dwBytesPerBlock;
sectorSize = flashInfo.wDataBytesPerSector;
sectorsPerBlock = flashInfo.wSectorsPerBlock;
// Skip reserved blocks
block = 0;
while (block < flashInfo.dwNumBlocks) {
if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
OALMSG(OAL_WARN, (L"WARN: EBOOT!FMD_GetBlockStatus: "
L"Skip bad block %d\r\n", block
));
block++;
continue;
}
if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_RESERVED) == 0) break;
block++;
}
// Set address where to place image
pImage = (UINT8*)IMAGE_WINCE_CODE_PA;
size = IMAGE_WINCE_CODE_SIZE;
// Read image to memory
offset = 0;
toc = 0;
pTOC = NULL;
while (offset < size && block < flashInfo.dwNumBlocks) {
// Skip bad blocks
if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) != 0) {
block++;
sector += flashInfo.wSectorsPerBlock;
continue;
}
// Read sectors in block
sector = 0;
while (sector < sectorsPerBlock && offset < size) {
// When block read fail, there isn't what we can do more
RETAILMSG(1, (TEXT("0x%x 0x%x \r\n"), block * sectorsPerBlock + sector, pImage + offset));
if (!FMD_ReadSector(
block * sectorsPerBlock + sector, pImage + offset,
§orInfo, 1
)) {
OALMSG(OAL_ERROR, (L"\r\nERROR: BLFlashDownload: "
L"Failed read sector %d from flash\r\n", sector
));
goto cleanUp;
}
// Move to next sector
sector++;
offset += sectorSize;
}
// Move to next block
block++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -