📄 nand.c
字号:
DWORD dwBlock;
do
{
OALMSG(1, (TEXT("Enter bad block number(1-%d): "), (g_FlashInfo.dwNumBlocks - 1)));
dwBlock = GetBlockNumberInput();
if(dwBlock >= 1 && dwBlock < g_FlashInfo.dwNumBlocks)
{
if(FMD_SetBlockStatus(dwBlock, BLOCK_STATUS_BAD) != TRUE)
OALMSG(OAL_ERROR, (TEXT("ERROR: Failed to set block %d bad.\r\n"), dwBlock));
else
OALMSG(OAL_INFO, (TEXT("INFO: block %d set as bad.\r\n"), dwBlock));
}
} while(dwBlock != -1);
}
else
OALMSG(OAL_INFO, (TEXT("INFO: NAND device non existent.\r\n")));
break;
case '9':
if(g_fNandExists == TRUE)
{
DWORD dwBlock;
DWORD dwStartBlock;
DWORD dwEndBlock;
while(1)
{
OALMSG(1, (TEXT("Enter erase start block number(0-%d): "), (g_FlashInfo.dwNumBlocks - 1)));
dwBlock = GetBlockNumberInput();
if(dwBlock != -1 && dwBlock >= 0 && dwBlock < g_FlashInfo.dwNumBlocks)
{
dwStartBlock = dwBlock;
break;
}
};
while(1)
{
OALMSG(1, (TEXT("Enter erase end block number(%d-%d): "), dwStartBlock, (g_FlashInfo.dwNumBlocks - 1)));
dwBlock = GetBlockNumberInput();
if(dwBlock < 0 || dwBlock > g_FlashInfo.dwNumBlocks || dwBlock < dwStartBlock)
{
OALMSG(1, (TEXT("Invalid block number %d\r\n"), dwBlock));
continue;
}
else
{
dwEndBlock = dwBlock;
break;
}
};
while(dwStartBlock <= dwEndBlock)
{
if(FMD_EraseBlock(dwStartBlock) != TRUE)
OALMSG(OAL_ERROR, (TEXT("ERROR: Failed to erase block %d.\r\n"), dwStartBlock));
else
OALMSG(1, (TEXT("INFO: block %d erased.\r\n"), dwStartBlock));
dwStartBlock++;
}
}
else
OALMSG(OAL_INFO, (TEXT("INFO: NAND device non existent.\r\n")));
break;
#endif
case 'b':
case 'B':
// Return To Main Menu.
bExitMenu = TRUE;
break;
default:
break;
}
} while(bExitMenu == FALSE);
return bImageExists;
}
//-----------------------------------------------------------------------------
// PRIVATE FUNCTIONS
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------**
//
// FUNCTION: GetKernelExtPointer
//
// DESCRIPTION: Used to locate the kernel region's extension area.
//
// PARAMETERS:
// dwRegionStart - start of region
// dwRegionLength - size of region
//
// RETURNS:
// Pointer to kernel's extension area. NULL if failure.
//-----------------------------------------------------------------------------
static PVOID GetKernelExtPointer(DWORD dwRegionStart, DWORD dwRegionLength)
{
DWORD dwCacheAddress = 0;
ROMHDR *pROMHeader;
DWORD dwNumModules = 0;
TOCentry *pTOC;
OALMSG(OAL_FUNC, (TEXT("GetKernelExtPointer+\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);
// 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -