📄 blcommon.c
字号:
return (FALSE);
}
// Is this a standard bin image? Check for the usual bin file signature.
//
else if (!memcmp (hdr, "B000FF\x0A", BL_HDRSIG_SIZE))
{
g_bBINDownload = TRUE;
if (!OEMReadData (sizeof (DWORD), (LPBYTE) &dwImageStart)
|| !OEMReadData (sizeof (DWORD), (LPBYTE) &dwImageLength))
{
EdbgOutputDebugString ("Unable to read image start/length\r\n");
HALT (BLERR_MAGIC);
return (FALSE);
}
}
// If the header signature isn't recognized, we'll assume the
// download file is a raw .nb0 file.
//
else
{
g_bBINDownload = FALSE;
}
// If Platform Builder didn't provide a download manifest (i.e., we're
// only downloading a single .bin file), manufacture a manifest so we
// can notify the OEM.
//
if (!g_DownloadManifest.dwNumRegions)
{
g_DownloadManifest.dwNumRegions = 1;
g_DownloadManifest.Region[0].dwRegionStart = dwImageStart;
g_DownloadManifest.Region[0].dwRegionLength = dwImageLength;
// Provide the download manifest to the OEM.
//
if (g_pOEMMultiBINNotify)
{
g_pOEMMultiBINNotify((PDownloadManifest)&g_DownloadManifest);
}
}
// Locate the current download manifest entry (current download file).
//
pCurDownloadFile = &g_DownloadManifest.Region[g_DownloadManifest.dwNumRegions - nNumDownloadFiles];
// give the OEM a chance to verify memory
if (g_pOEMVerifyMemory && !g_pOEMVerifyMemory (pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionLength))
{
EdbgOutputDebugString ("!OEMVERIFYMEMORY: Invalid image\r\n");
HALT (BLERR_OEMVERIFY);
return (FALSE);
}
// check for flash image. Start erasing if it is.
if ((fIsFlash = OEMIsFlashAddr (pCurDownloadFile->dwRegionStart))
&& !OEMStartEraseFlash (pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionLength))
{
EdbgOutputDebugString ("Invalid Flash Address/Length\r\n");
HALT (BLERR_FLASHADDR);
return (FALSE);
}
// if we're downloading a binary file, we've already downloaded part of the image when searching
// for a file header. copy what we've read so far to the destination buffer, then finish downloading.
if (!g_bBINDownload)
{
lpDest = OEMMapMemAddr (pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart);
memcpy(lpDest, hdr, BL_HDRSIG_SIZE);
// complete the file download...
// read data block
if (!OEMReadData ((pCurDownloadFile->dwRegionLength - BL_HDRSIG_SIZE), (lpDest + BL_HDRSIG_SIZE)))
{
EdbgOutputDebugString ("ERROR: failed when reading raw binary file.\r\n");
HALT (BLERR_CORRUPTED_DATA);
return (FALSE);
}
}
// we're downloading a .bin file - download each .bin record in turn...
else
{
while (OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecAddr) &&
OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecLen) &&
OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecChk))
{
// last record of .bin file uses sentinel values for address and checksum.
if (!dwRecAddr && !dwRecChk)
{
break;
}
// map the record address (FLASH data is cached, for example)
lpDest = OEMMapMemAddr (pCurDownloadFile->dwRegionStart, dwRecAddr);
// read data block
if (!OEMReadData (dwRecLen, lpDest))
{
EdbgOutputDebugString ("****** Data record %d corrupted, ABORT!!! ******\r\n", nPkgNum);
HALT (BLERR_CORRUPTED_DATA);
return (FALSE);
}
if (!VerifyChecksum (dwRecLen, lpDest, dwRecChk))
{
EdbgOutputDebugString ("****** Checksum failure on record %d, ABORT!!! ******\r\n", nPkgNum);
HALT (BLERR_CHECKSUM);
return (FALSE);
}
// Look for ROMHDR to compute ROM offset. NOTE: romimage guarantees that the record containing
// the TOC signature and pointer will always come before the record that contains the ROMHDR contents.
//
if (dwRecLen == sizeof(ROMHDR) && (*(LPDWORD) OEMMapMemAddr(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE))
{
DWORD dwTempOffset = (dwRecAddr - *(LPDWORD)OEMMapMemAddr(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart + ROM_SIGNATURE_OFFSET + sizeof(ULONG)));
ROMHDR *pROMHdr = (ROMHDR *)lpDest;
// Check to make sure this record really contains the ROMHDR.
//
if ((pROMHdr->physfirst == (pCurDownloadFile->dwRegionStart - dwTempOffset)) &&
(pROMHdr->physlast == (pCurDownloadFile->dwRegionStart - dwTempOffset + pCurDownloadFile->dwRegionLength)) &&
(DWORD)(HIWORD(pROMHdr->dllfirst << 16) <= pROMHdr->dlllast) &&
(DWORD)(LOWORD(pROMHdr->dllfirst << 16) <= pROMHdr->dlllast))
{
g_dwROMOffset = dwTempOffset;
EdbgOutputDebugString("rom_offset=0x%x.\r\n", g_dwROMOffset);
}
}
// verify partial checksum
OEMShowProgress (nPkgNum ++);
if (fIsFlash)
{
OEMContinueEraseFlash ();
}
}
}
// The image start address and length are passed back to the OEM code (OEMLaunch)
// in the following circumstances:
// 1. The file is a raw .nb0 file.
// 2. The file is a .bin file with a TOC that contains the kernel executable.
// 3. The file is a .bin file without a TOC.
//
// If the image is a .bin file with a TOC that doesn't contain the kernel exectuable,
// then it's a multi-xip/mulit-bin image for a non-kernel region and we don't pass
// the start address and length back to the OEM code. OEMLaunch can then save the
// start address and length with the assurance that if the values are non-zero, they
// represent the values for the NK region.
//
if (g_bBINDownload)
{
// Does this .bin file contain a TOC?
if (*(LPDWORD) OEMMapMemAddr(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE)
{
// Contain the kernel?
if (IsKernelRegion(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionLength))
{
*pdwImageStart = pCurDownloadFile->dwRegionStart;
*pdwImageLength = pCurDownloadFile->dwRegionLength;
*pdwLaunchAddr = dwRecLen;
}
}
// No TOC - not made by romimage. However, if we're downloading more than one
// .bin file, it's probably chain.bin which doesn't have a TOC (and which isn't
// going to be downloaded on its own) and we should ignore it.
//
else if (g_DownloadManifest.dwNumRegions == 1)
{
*pdwImageStart = pCurDownloadFile->dwRegionStart;
*pdwImageLength = pCurDownloadFile->dwRegionLength;
*pdwLaunchAddr = dwRecLen;
}
}
else // Raw binary file.
{
*pdwImageStart = pCurDownloadFile->dwRegionStart;
*pdwLaunchAddr = pCurDownloadFile->dwRegionStart;
*pdwImageLength = pCurDownloadFile->dwRegionLength;
}
// write to flash if it's flash image
if (fIsFlash)
{
// finish the flash erase
if (!OEMFinishEraseFlash ())
{
HALT (BLERR_FLASH_ERASE);
return (FALSE);
}
// Before writing the image to flash, optionally check the image signature.
if (g_bBINDownload && g_pOEMCheckSignature)
{
if (!g_pOEMCheckSignature(pCurDownloadFile->dwRegionStart, g_dwROMOffset, *pdwLaunchAddr, TRUE))
HALT(BLERR_CAT_SIGNATURE);
}
}
}
while (--nNumDownloadFiles);
if (fIsFlash)
{
nNumDownloadFiles = (BYTE)g_DownloadManifest.dwNumRegions;
while (nNumDownloadFiles--)
{
if (!OEMWriteFlash (g_DownloadManifest.Region[nNumDownloadFiles].dwRegionStart, g_DownloadManifest.Region[nNumDownloadFiles].dwRegionLength))
{
HALT (BLERR_FLASH_WRITE);
return (FALSE);
}
}
}
return (TRUE);
}
/*
@func BOOLEAN | IsKernelRegion | Determines if the expanded BIN file provided contains the kernel image.
@rdesc TRUE if the region contains the kernel image, FALSE if it doesn't.
@comm <l Download Image>
@xref
@notes dwCurrentBase is the base address where the BIN records are currently stored (this can be a RAM, a RAM
file cache, or flash). dwImageStoreBase is the images base storage address (this is the base address of potentially
multiple BIN regions and can be in RAM or flash) and is used to translate addresses to the file cache area.
dwROMOffset is the difference between the address where the BIN records are stored versus where they're fixed-up
to run from (for example, an image may be stored in flash, but fixed-up to run in RAM).
*/
static BOOL IsKernelRegion(DWORD dwRegionStart, DWORD dwRegionLength)
{
DWORD dwCacheAddress = 0;
ROMHDR *pROMHeader;
DWORD dwNumModules = 0;
TOCentry *plTOC;
if (dwRegionStart == 0 || dwRegionLength == 0)
return(FALSE);
if (*(LPDWORD) OEMMapMemAddr (dwRegionStart, dwRegionStart + ROM_SIGNATURE_OFFSET) != ROM_SIGNATURE)
return (FALSE);
// 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 + g_dwROMOffset);
// Make sure sure are some modules in the table of contents.
//
if ((dwNumModules = pROMHeader->nummods) == 0)
return (FALSE);
// Locate the table of contents and search for the kernel executable and the TOC immediately follows the ROMHDR.
//
plTOC = (TOCentry *)(pROMHeader + 1);
while(dwNumModules--) {
LPBYTE pFileName = OEMMapMemAddr(dwRegionStart, (DWORD)plTOC->lpszFileName + g_dwROMOffset);
if (!strcmp(pFileName, "nk.exe")) {
return TRUE;
}
++plTOC;
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -