?? nand.cpp
字號:
return FALSE;
}
// is it a valid image descriptor?
if ( !VALID_IMAGE_DESCRIPTOR(&g_pTOC->id[g_dwTocEntry]) ) {
EdbgOutputDebugString("TOC_Write ERROR: INVALID_IMAGE[%u] Signature: 0x%x\r\n",
g_dwTocEntry, g_pTOC->id[g_dwTocEntry].dwSignature);
return FALSE;
}
// in order to write a sector we must erase the entire block first
// !! BUGBUG: must cache the TOC first so we don't trash other image descriptors !!
if ( !FMD_EraseBlock(TOC_BLOCK) ) {
RETAILMSG(1, (TEXT("TOC_Write ERROR: EraseBlock[%d] \r\n"), TOC_BLOCK));
return FALSE;
}
// setup our metadata so filesys won't stomp us
si.dwReserved1 = 0;
si.bOEMReserved = ~(OEM_BLOCK_RESERVED | OEM_BLOCK_READONLY); // NAND cannot set bit 0->1
si.bBadBlock = BADBLOCKMARK;
si.wReserved2 = 0xffff;
// write the sector & metadata
if ( !FMD_WriteSector(TOC_SECTOR, (PUCHAR)&g_TOC, &si, 1) ) {
EdbgOutputDebugString("TOC_Write ERROR: Unable to save TOC\r\n");
return FALSE;
}
// read it back & verify both data & metadata
if ( !FMD_ReadSector(TOC_SECTOR, (PUCHAR)&toc, &si2, 1) ) {
EdbgOutputDebugString("TOC_Write ERROR: Unable to read/verify TOC\r\n");
return FALSE;
}
if ( 0 != memcmp(&g_TOC, &toc, SECTOR_SIZE) ) {
EdbgOutputDebugString("TOC_Write ERROR: TOC verify failed\r\n");
return FALSE;
}
if ( 0 != memcmp(&si, &si2, sizeof(si)) ) {
EdbgOutputDebugString("TOC_Write ERROR: SectorInfo verify failed: %x %x %x %x\r\n",
si.dwReserved1, si.bOEMReserved, si.bBadBlock, si.wReserved2);
return FALSE;
}
EdbgOutputDebugString("-TOC_Write\r\n");
return TRUE;
}
/*
@func void | DumpXIPChainSummary | Dump XIPCHAIN_SUMMARY structure
@rdesc none
@comm
@xref
*/
void DumpXIPChainSummary(PXIPCHAIN_SUMMARY pChainInfo)
{
EdbgOutputDebugString("[Dump XIP Chain Summary]\r\n");
EdbgOutputDebugString(" - pvAddr: 0x%x\r\n", pChainInfo->pvAddr);
EdbgOutputDebugString(" - dwMaxLength : %d\r\n", pChainInfo->dwMaxLength);
EdbgOutputDebugString(" - usOrder : 0x%x\r\n", pChainInfo->usOrder);
EdbgOutputDebugString(" - usFlags : 0x%x\r\n", pChainInfo->usFlags);
EdbgOutputDebugString(" - reserved : 0x%x\r\n", pChainInfo->reserved);
}
/*
@func BOOL | WriteOSImageToBootMedia | Stores the image cached in RAM to the Boot Media.
The image may be comprised of one or more BIN regions.
@rdesc TRUE = Success, FALSE = Failure.
@comm
@xref
*/
BOOL WriteOSImageToBootMedia(DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr)
{
BYTE nCount;
DWORD dwNumExts;
PXIPCHAIN_SUMMARY pChainInfo = NULL;
EXTENSION *pExt = NULL;
DWORD dwBINFSPartLength = 0;
HANDLE hPart, hPartEx;
DWORD dwStoreOffset;
DWORD dwMaxRegionLength[BL_MAX_BIN_REGIONS] = {0};
DWORD dwChainStart, dwChainLength;
DWORD dwBlock;
// Initialize the variables
dwChainStart = dwChainLength = 0;
OALMSG(OAL_FUNC, (TEXT("+WriteOSImageToBootMedia\r\n")));
OALMSG(OAL_INFO, (TEXT("+WriteOSImageToBootMedia: g_dwTocEntry =%d, ImageStart: 0x%x, ImageLength: 0x%x, LaunchAddr:0x%x\r\n"),
g_dwTocEntry, dwImageStart, dwImageLength, dwLaunchAddr));
if ( !g_bBootMediaExist )
{
OALMSG(OAL_ERROR, (TEXT("ERROR: WriteOSImageToBootMedia: device doesn't exist.\r\n")));
return(FALSE);
}
if (g_ImageType == IMAGE_TYPE_RAMIMAGE)
{
dwBlock = IMAGE_START_BLOCK + 1;
// dwImageStart += dwLaunchAddr;
// dwImageLength = dwImageLength; //step loader can support 4k bytes only. NO SuperIPL case is 16K....... 3 Block
}
if ( !VALID_TOC(g_pTOC) )
{
OALMSG(OAL_WARN, (TEXT("WARN: WriteOSImageToBootMedia: INVALID_TOC\r\n")));
if ( !TOC_Init(g_dwTocEntry, g_ImageType, dwImageStart, dwImageLength, dwLaunchAddr) )
{
OALMSG(OAL_ERROR, (TEXT("ERROR: INVALID_TOC\r\n")));
return(FALSE);
}
}
// Look in the kernel region's extension area for a multi-BIN extension descriptor.
// This region, if found, details the number, start, and size of each BIN region.
//
for (nCount = 0, dwNumExts = 0 ; (nCount < g_BINRegionInfo.dwNumRegions); nCount++)
{
// Does this region contain nk.exe and an extension pointer?
//
pExt = (EXTENSION *)GetKernelExtPointer(g_BINRegionInfo.Region[nCount].dwRegionStart,
g_BINRegionInfo.Region[nCount].dwRegionLength );
EdbgOutputDebugString("INFO: %s: [%d] RegionStart:0x%x, RegionLength:0x%x, pExt:0x%x\r\n",
__FUNCTION__, nCount,
g_BINRegionInfo.Region[nCount].dwRegionStart,
g_BINRegionInfo.Region[nCount].dwRegionLength,
pExt);
if ( pExt != 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);
EdbgOutputDebugString("INFO: %s: [%d] Found chain extension: '%s' @ 0x%x\r\n", __FUNCTION__, nCount, pExt->name, dwBaseAddr);
if ((pExt->type == 0) && !strcmp(pExt->name, "chain information"))
{
pChainInfo = (PXIPCHAIN_SUMMARY) OEMMapMemAddr(dwBaseAddr, (DWORD)pExt->pdata);
dwNumExts = (pExt->length / sizeof(XIPCHAIN_SUMMARY));
EdbgOutputDebugString("INFO: %s: [%d] Found 'chain information' (pChainInfo=0x%x Extensions=0x%x).\r\n", __FUNCTION__, nCount, (DWORD)pChainInfo, dwNumExts);
DumpXIPChainSummary(pChainInfo);
dwChainStart = (DWORD)pChainInfo->pvAddr;
dwChainLength = pChainInfo->dwMaxLength;
goto FoundChainAddress;
}
pExt = (EXTENSION *)pExt->pNextExt;
}
}
else {
// Search for Chain region. Chain region doesn't have the ROMSIGNATURE set
EdbgOutputDebugString("Not Found pExtPointer, Check if this is Chain region.\n");
DWORD dwRegionStart = g_BINRegionInfo.Region[nCount].dwRegionStart;
DWORD dwSig = *(LPDWORD) OEMMapMemAddr(dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET);
if ( dwSig != ROM_SIGNATURE) {
// It is the chain
dwChainStart = dwRegionStart;
dwChainLength = g_BINRegionInfo.Region[nCount].dwRegionLength;
OALMSG(TRUE, (TEXT("Found the Chain region: StartAddress: 0x%X; Length: 0x%X\n"), dwChainStart, dwChainLength));
}
}
}
FoundChainAddress:
// Determine how big the Total BINFS partition needs to be to store all of this.
//
if (pChainInfo && dwNumExts == g_BINRegionInfo.dwNumRegions) // We're downloading all the regions in a multi-region image...
{
DWORD i;
OALMSG(TRUE, (TEXT("Writing multi-regions : Total %d regions\r\n"), dwNumExts));
for (nCount = 0, dwBINFSPartLength = 0 ; nCount < dwNumExts ; nCount++)
{
dwBINFSPartLength += (pChainInfo + nCount)->dwMaxLength;
OALMSG(OAL_ERROR, (TEXT("[%u] BINFSPartMaxLength: 0x%x, TtlBINFSPartLength: 0x%x \r\n"),
nCount, (pChainInfo + nCount)->dwMaxLength, dwBINFSPartLength));
// MultiBINInfo does not store each Regions MAX length, and pChainInfo is not in any particular order.
// So, walk our MultiBINInfo matching up pChainInfo to find each regions MAX Length
for (i = 0; i < dwNumExts; i++) {
if ( g_BINRegionInfo.Region[i].dwRegionStart == (DWORD)((pChainInfo + nCount)->pvAddr) ) {
dwMaxRegionLength[i] = (pChainInfo + nCount)->dwMaxLength;
OALMSG(TRUE, (TEXT("dwMaxRegionLength[%u]: 0x%x \r\n"), i, dwMaxRegionLength[i]));
break;
}
}
}
}
else // A single BIN file or potentially a multi-region update (but the partition's already been created in this latter case).
{
dwBINFSPartLength = g_BINRegionInfo.Region[0].dwRegionLength;
OALMSG(TRUE, (TEXT("Writing single region/multi-region update, dwBINFSPartLength: %u \r\n"), dwBINFSPartLength));
}
// Open/Create the BINFS partition where images are stored. This partition starts immediately after the MBR on the Boot Media and its length is
// determined by the maximum image size (or sum of all maximum sizes in a multi-region design).
// Parameters are LOGICAL sectors.
//
hPart = BP_OpenPartition( (IMAGE_START_BLOCK+1)*PAGES_PER_BLOCK, // next block of MBR
SECTOR_TO_BLOCK_SIZE(FILE_TO_SECTOR_SIZE(dwBINFSPartLength))*PAGES_PER_BLOCK, // align to block
PART_BINFS,
TRUE,
PART_OPEN_ALWAYS);
if (hPart == INVALID_HANDLE_VALUE )
{
OALMSG(OAL_ERROR, (TEXT("ERROR: WriteOSImageToBootMedia: Failed to open/create partition.\r\n")));
return(FALSE);
}
// Are there multiple BIN files in RAM (we may just be updating one in a multi-BIN solution)?
//
for (nCount = 0, dwStoreOffset = 0; nCount < g_BINRegionInfo.dwNumRegions ; nCount++)
{
EdbgOutputDebugString("BIN Region Number : %d\r\n", nCount);
DWORD dwRegionStart = (DWORD)OEMMapMemAddr(0, g_BINRegionInfo.Region[nCount].dwRegionStart);
DWORD dwRegionLength = g_BINRegionInfo.Region[nCount].dwRegionLength;
// Media byte offset where image region is stored.
dwStoreOffset += nCount ? dwMaxRegionLength[nCount-1] : 0;
// Set the file pointer (byte indexing) to the correct offset for this particular region.
//
if ( !BP_SetDataPointer(hPart, dwStoreOffset) )
{
OALMSG(OAL_ERROR, (TEXT("ERROR: StoreImageToBootMedia: Failed to set data pointer in partition (offset=0x%x).\r\n"), dwStoreOffset));
return(FALSE);
}
// Write the region to the BINFS partition.
if ( !BP_WriteData(hPart, (LPBYTE)dwRegionStart, dwRegionLength) )
{
EdbgOutputDebugString("ERROR: StoreImageToBootMedia: Failed to write region to BINFS partition (start=0x%x, length=0x%x).\r\n", dwRegionStart, dwRegionLength);
return(FALSE);
}
if(nCount > 1) // We will skip Region 0 -> for bootloader
{
}
// update TOC, when we reach to last TOC entry.
if ((g_pTOC->id[g_dwTocEntry].dwLoadAddress == g_BINRegionInfo.Region[nCount].dwRegionStart) &&
g_pTOC->id[g_dwTocEntry].dwTtlSectors == FILE_TO_SECTOR_SIZE(dwRegionLength) )
{
g_pTOC->id[g_dwTocEntry].dwStoreOffset = dwStoreOffset;
g_pTOC->id[g_dwTocEntry].dwJumpAddress = 0; // Filled upon return to OEMLaunch
g_pTOC->id[g_dwTocEntry].dwImageType = g_ImageType;
g_pTOC->id[g_dwTocEntry].sgList[0].dwSector = FILE_TO_SECTOR_SIZE(g_dwLastWrittenLoc);
g_pTOC->id[g_dwTocEntry].sgList[0].dwLength = g_pTOC->id[g_dwTocEntry].dwTtlSectors;
// copy Kernel Region to SDRAM for jump
memcpy((void*)g_pTOC->id[g_dwTocEntry].dwLoadAddress, (void*)dwRegionStart, dwRegionLength);
OALMSG(TRUE, (TEXT("Update Last TOC[%d] Entry to TOC cache in memory!\r\n"), g_pTOC->id[g_dwTocEntry]));
}
/* needed only if RAMIMAGE type of multiple-XIP is used
else if( (dwChainStart == g_BINRegionInfo.Region[nCount].dwRegionStart) &&
(dwChainLength == g_BINRegionInfo.Region[nCount].dwRegionLength))
{
// Update our TOC for Chain region
g_pTOC->chainInfo.dwLoadAddress = dwChainStart;
g_pTOC->chainInfo.dwFlashAddress = FILE_TO_SECTOR_SIZE(g_dwLastWrittenLoc);
g_pTOC->chainInfo.dwLength = FILE_TO_SECTOR_SIZE(dwMaxRegionLength[nCount]);
OALMSG(TRUE, (TEXT("Written Chain Region to the Flash\n")));
OALMSG(TRUE, (TEXT("LoadAddress = 0x%X; FlashAddress = 0x%X; Length = 0x%X\n"),
g_pTOC->chainInfo.dwLoadAddress,
g_pTOC->chainInfo.dwFlashAddress,
g_pTOC->chainInfo.dwLength));
// Now copy it to the SDRAM
memcpy((void *)g_pTOC->chainInfo.dwLoadAddress, (void *)dwRegionStart, dwRegionLength);
}
else // Other TOC Type Just fill it.
{
g_pTOC->id[nCount].dwStoreOffset = dwStoreOffset;
g_pTOC->id[nCount].dwJumpAddress = 0; // Filled upon return to OEMLaunch
g_pTOC->id[nCount].dwImageType = g_ImageType;
g_pTOC->id[nCount].sgList[0].dwSector = FILE_TO_SECTOR_SIZE(g_dwLastWrittenLoc);
g_pTOC->id[nCount].sgList[0].dwLength = g_pTOC->id[nCount].dwTtlSectors;
// copy Kernel Region to SDRAM for jump (only if RAMIMAGE multiple-XIP is used)
//memcpy((void*)g_pTOC->id[nCount].dwLoadAddress, (void*)dwRegionStart, dwRegionLength);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -