fmd.cpp
来自「S3C24A0的完整BSP包,对开发此芯片的开发者很有用.」· C++ 代码 · 共 840 行 · 第 1/3 页
CPP
840 行
}
//
// Store TOC to Nand
// BUGBUG: only uses 1 sector for now.
//
BOOL TOC_Write(void)
{
SectorInfo si, si2;
EdbgOutputDebugString("+TOC_Write\r\n");
if ( !g_bBootMediaExist ) {
EdbgOutputDebugString("TOC_Write WARN: no boot media\r\n");
return FALSE;
}
// is it a valid TOC?
if ( !VALID_TOC(g_pTOC) ) {
EdbgOutputDebugString("TOC_Write ERROR: INVALID_TOC Signature: 0x%x\r\n", g_pTOC->dwSignature);
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 !!
// RETAILMSG(1, (TEXT("Erasing Block: %u\r\n"), TOC_BLOCK));
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;
si.bBadBlock = BADBLOCKMARK;
si.wReserved2 = 0;
// write the sector & metadata
// RETAILMSG(1, (TEXT("FMD_WriteSector............. \r\n")));
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
// RETAILMSG(1, (TEXT("FMD_ReadSector............. \r\n")));
if ( !FMD_ReadSector(TOC_SECTOR, (PUCHAR)&toc, &si2, 1) ) {
EdbgOutputDebugString("TOC_Write ERROR: Unable to read/verify TOC\r\n");
return FALSE;
}
// RETAILMSG(1, (TEXT("memcmp............. \r\n")));
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;
}
// TOC_Print();
EdbgOutputDebugString("-TOC_Write\r\n");
return TRUE;
}
/*
@func PVOID | GetKernelExtPointer | Locates the kernel region's extension area pointer.
@rdesc Pointer to the kernel's extension area.
@comm
@xref
*/
PVOID GetKernelExtPointer(DWORD dwRegionStart, DWORD dwRegionLength)
{
DWORD dwCacheAddress = 0;
ROMHDR *pROMHeader;
DWORD dwNumModules = 0;
TOCentry *pTOC;
if (dwRegionStart == 0 || dwRegionLength == 0)
return(NULL);
if (*(LPDWORD) OEMMapMemAddr(dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET) != ROM_SIGNATURE)
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 there are some modules in the table of contents.
//
if ((dwNumModules = pROMHeader->nummods) == 0)
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);
// EdbgOutputDebugString("GetKernelExtPointer: found module[%u]: %s\r\n", dwNumModules, pFileName);
if (!strcmp((const char *)pFileName, "nk.exe")) {
return ((PVOID)(pROMHeader->pExtensions));
}
++pTOC;
}
return NULL;
}
/*
@func BOOL | WriteRegionsToBootMedia | 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 WriteRegionsToBootMedia(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;
// Initialize the variables
dwChainStart = dwChainLength = 0;
EdbgOutputDebugString("+WriteRegionsToBootMedia: ImageStart: 0x%x, ImageLength: 0x%x, LaunchAddr:0x%x\r\n",
dwImageStart, dwImageLength, dwLaunchAddr);
if ( !g_bBootMediaExist ) {
EdbgOutputDebugString("ERROR: WriteRegionsToBootMedia: device doesn't exist.\r\n");
return(FALSE);
}
if ( !VALID_TOC(g_pTOC) ) {
EdbgOutputDebugString("WARN: WriteRegionsToBootMedia: INVALID_TOC\r\n");
if ( !TOC_Init(g_dwTocEntry, g_ImageType, dwImageStart, dwImageLength, dwLaunchAddr) ) {
EdbgOutputDebugString("ERROR: INVALID_TOC\r\n");
return(FALSE);
}
}
if ( !(IMAGE_TYPE_BINFS & g_pTOC->id[g_dwTocEntry].dwImageType) ) {
EdbgOutputDebugString("ERROR: WriteRegionsToBootMedia: INVALID_IMAGE_TYPE: 0x%x\r\n",
g_pTOC->id[g_dwTocEntry].dwImageType);
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) && !pChainInfo ; nCount++)
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 );
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: OEMLaunch: Found chain extenstion: '%s' @ 0x%x\r\n", 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: OEMLaunch: Found 'chain information' (pChainInfo=0x%x Extensions=0x%x).\r\n", (DWORD)pChainInfo, dwNumExts);
break;
}
pExt = (EXTENSION *)pExt->pNextExt;
}
}
else {
// Search for Chain region. Chain region doesn't have the ROMSIGNATURE set
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;
EdbgOutputDebugString("Found the Chain region: StartAddress: 0x%X; Length: 0x%X\n", dwChainStart, dwChainLength);
}
}
}
// 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;
EdbgOutputDebugString("Writing multi-regions\r\n");
for (nCount = 0, dwBINFSPartLength = 0 ; nCount < dwNumExts ; nCount++)
{
dwBINFSPartLength += (pChainInfo + nCount)->dwMaxLength;
EdbgOutputDebugString("BINFSPartMaxLength[%u]: 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;
EdbgOutputDebugString("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;
EdbgOutputDebugString("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( NEXT_FREE_LOC,
FILE_TO_SECTOR_SIZE(dwBINFSPartLength) + 1, // sizeof image + MBR sector
PART_BINFS,
TRUE,
PART_OPEN_ALWAYS);
*/
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 )
{
EdbgOutputDebugString("ERROR: WriteRegionsToBootMedia: Failed to open/create BINFS 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++)
{
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;
EdbgOutputDebugString("dwRegionStart: 0x%x, dwRegionLength: 0x%x, dwStoreOffset: 0x%x\r\n",
dwRegionStart, dwRegionLength, dwStoreOffset);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?