在看DownloaderImage的时候遇见一些问题,希望各位能够指点小弟一二:
1. // verify the packet checksum.
//
if (!VerifyChecksum((g_DownloadManifest.dwNumRegions * sizeof(RegionInfo)), (LPBYTE) &g_DownloadManifest.Region[0], dwRecChk))
{
KITLOutputDebugString ("\r\nDownload manifest packet failed checksum verification.\r\n");
HALT (BLERR_CHECKSUM);
return (FALSE);
}
这里校验的原理是什么?
追踪static BOOL VerifyChecksum (DWORD cbRecord, LPBYTE pbRecord, DWORD dwChksum)
{
// Check the CRC
DWORD dwCRC = 0;
DWORD i;
for (i = 0; i < cbRecord; i++)
dwCRC += *pbRecord ++;
if (dwCRC != dwChksum)
KITLOutputDebugString ("ERROR: Checksum failure (expected=0x%x computed=0x%x)\r\n", dwChksum, dwCRC);
return (dwCRC == dwChksum);
}
我的理解是记录条目的总和和获得的4字节的校验数据作比较?请问是这样理解的嘛?
2. // 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;
......
}
这里面的OEMMapMemAddr最后返回的地址到底是什么?
3.查看NK.bin,镜像运行时偏移地址0X40位置处的数据刚好是0X43454345,紧随其后的是4字节的镜像运行时的ImageStart。
在romldr.h中有如下定义:
#define ROM_SIGNATURE_OFFSET 0X40
#define ROM_SIGNATURE 0X43454345
可是上面这句话:
if (dwRecLen == sizeof(ROMHDR) && (*(LPDWORD) OEMMapMemAddr(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE))
查看MSDN,OEMMapMemAddr返回的是个地址,而ROM_SIGNATURE是个数据啊,应该怎么理解呢?
问题有点多,还望不要嫌烦!呵呵~~~
以下翻译来自MSDN,自己生吞活剥的,翻译的不准确,希望各位指出:
This function handles downloads that are destined for flash. OEMmapMemAddr remaps a flash-resident address to a unique RAM-based address so that flash memory OS images can be temporarily cached in RAM while the download occurs. This provides enough time to handle the flash memory update while not stalling the download process because the flash memory operation typically takes more time than the download process.
这个函数处理目的是flash的下载。OEMmapMemAddr 重映射一个常驻flash的地址到一个唯一基于RAM的地址,所以flash内存中的操作系统镜像在下载的时候可以临时的缓存到RAM。这就提供了足够的时间去处理flash内存的更新而不是存储,在下载的时候。这是因为flash内存在进行操作的时候存储的时间要比下载的过程要花费更多的时间。
句式:
LPBYTE OEMMapMemAddr(
DWORD dwImageStart,
DWORD dwAddr
);
参数:
dwImageStart
[in] Starting address of OS image.
[in]OS镜像的起始地址
dwAddr
[in] Address of a BIN record. If this address lies in a platform's flash memory address space, typically the offset from dwImageStart is computed and added to a RAM-based file cache area.
[in] BIN记录的地址。如果这个地址位于平台flash内存的地址空间,典型地做法是计算OS起始地址的偏移,并且再加到一个基于RAM缓存文件区域。
返回值:
Address from which the BIN record should be copied to provide file caching before and during the flash update process.
在flash更新过程之前和之中,返回一个BIN记录应该被复制到提供的文件缓存的地址。
要求:
Header blcommon.h
Library blcommon.lib
Windows Embedded CE Windows CE .NET 4.0 and later
各位知道的都说说嘛?问题可能有点多,但是我觉得应该集思广益嘛~~~或者我有什么地方不对的也可以说出来啊!
刚才又看了下代码,发现:
if (dwRecLen == sizeof(ROMHDR) && (*(LPDWORD) OEMMapMemAddr(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE))
//ROMHDR这个结构体共占用84(0x54)字节,判断是否与记录的长度相等。如果大小相等,则PTOC所指向的内存//区域的操作系统镜像数据保存在该记录中。&&后面的语句应该是该镜像记录的起始存储地址加上//ROM_SIGNATURE_OFFSET(0X40)是否等于 ROM_SIGNATURE(0x43454345)
{
DWORD dwTempOffset = (dwRecAddr - *(LPDWORD)OEMMapMemAddr(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart + ROM_SIGNATURE_OFFSET + sizeof(ULONG)));
//这句话我是这样理解的:dwTempOffset 看字面意思应该是一个临时(或者中间过渡用的)用的地址的偏移。
//dwRecAddr应该是指找到pTOC记录的该条记录的地址,再减去该镜像的起始地址(个人理解是第一条记录的起//始地址),就是该记录到起始基隆路的偏移地址,再加上4个字节就是该机流露的imageStart。
ROMHDR *pROMHdr = (ROMHDR *)lpDest;
......
}
希望后面的兄弟伙帮我顶起!
谢谢!
1 我的理解是记录条目的总和和获得的4字节的校验数据作比较?请问是这样理解的嘛?
是这样的。
2 这里面的OEMMapMemAddr最后返回的地址到底是什么?
在EBOOT的WriteRawImageToBootMedia函数中调用了OEMMapMemAddr,返回的地址是所要烧录数据的地址。
第三个问题你看下EBOOT中OEMMapMemAddr函数的具体内容对理解可能会有帮助。
第二个问题,按照MSDN原话:Address from which the BIN record should be copied to provide file caching before and during the flash update process.
我认为应该是找到pTOC所在记录的imageStart。我世界和后面代码的理解得出这个结论的,不知道这个理解对不对?
第三个问题,我想应该这么理解:
if (dwRecLen == sizeof(ROMHDR) && (*(LPDWORD) OEMMapMemAddr(pCurDownloadFile->dwRegionStart, pCurDownloadFile->dwRegionStart + ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE))
//该镜像记录的起始存储地址加上ROM_SIGNATURE_OFFSET(0X40)(也就是偏移0x40)后的数据是否等于 //ROM_SIGNATURE(0x43454345),因为OEMMapMemAddr前面还有*(LPDWORD),呵呵~~
以上理解不知道是否正确?还望大家共同提出意见!
借用Veabol兄博客的EBOOT.BIN例子
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000000 42 30 30 30 46 46 0A 00 80 03 80 88 20 07 00 00 B000FF..?.??...
00000010 80 03 80 04 00 00 00 E2 01 00 00 9B 5C 01 EA 40 ?.?....?..沑.闌
00000020 80 03 80 08 00 00 00 F1 02 00 00 45 43 45 43 F0 ?.?....?..ECEC?
00000030 67 0A 80 48 80 03 80 04 00 00 00 DD 01 00 00 F0 g.?H?.?....?..
我觉得应该是这样的:EBOOT.BIN和NK.BIN被分为了很多段上面04 00 00 00就是一个dwRecLen对应9B 5C 01 EA 这4个字节的数据,地址为8003800
然后往后是dwRecAddr=80038040 dwRecLen= 08 00 00 00 dwRecChk=F1 02 00 00 这个校验和为45 43 45 43 F0 67 0A 808个字节的数据之和,这个是通过VerifyChecksum()函数计算的。下面个段一次类推~~~·直到调用
// last record of .bin file uses sentinel values for address and checksum.
if (!dwRecAddr && !dwRecChk)
{
break;
}
函数后,BIN文件下载完成。
在EBOOT的WriteRawImageToBootMedia函数中调用了OEMMapMemAddr()
我觉得OEMMapMemAddr()应该是先吧数据放到CACHE中吧,返回的应该是CACHE的地址。。
LPBYTE OEMMapMemAddr(
DWORD dwImageStart,
DWORD dwAddr
);
参数:
dwImageStart
[in] Starting address of OS image.
[in]OS镜像的起始地址
dwAddr
[in] Address of a BIN record. If this address lies in a platform's flash memory address space, typically the offset from dwImageStart is computed and added to a RAM-based file cache area.
[in] BIN记录的地址。如果这个地址位于平台flash内存的地址空间,典型地做法是计算OS起始地址的偏移,并且再加到一个基于RAM缓存文件区域。
返回值:
Address from which the BIN record should be copied to provide file caching before and during the flash update process.
在flash更新过程之前和之中,返回一个BIN记录应该被复制到提供的文件缓存的地址。
要求:
Header blcommon.h
Library blcommon.lib
Windows Embedded CE Windows CE .NET 4.0 and later
啊~已经有解释了~不好意思 没仔细看~
引用: 引用 6 楼 lightsoure 的回复:
借用Veabol兄博客的EBOOT.BIN例子
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000000 42 30 30 30 46 46 0A 00 80 03 80 88 20 07 00 00 B000FF..?.??...
00000010 80……
可是这个CACHE的地址是在RAM中还是NANDFLASH中呢?
我的理解应该是RAM中吧,这个时候还没有校验,CACHE指的就是缓存在RAM中,然后经过校验后下载到NAND FLASH里面。
据你所说:dwRecChk=F1 02 00 00 这个校验和为45 43 45 43 F0 67 0A 80 8个字节的数据之和,这个是通过VerifyChecksum()函数计算的。而在这个函数中:
for (i = 0; i < cbRecord; i++)
dwCRC += *pbRecord ++;
//dwCRC应该就是这8个字节的和
if (dwCRC != dwChksum)
//dwChksum应该就是dwRecChk
这里判断的应该就是dwRecChk和dwCRC 是否相等。相等就进行下载。
我现在有个疑点就是45 43 45 43 F0 67 0A 80 8个字节的数据之和怎么相加才能等于dwRecChk=F1 02 00 00 这个校验和呢?
希望再指点下哈~~~
嘿嘿~~
0x45+0x43+0x45+0x43+0xF0+0x67+0x0A+0x80=0x2F1.
这不就是dwRecChk=F1 02 00 00 嘛
The little endian and big endian mode is desired by the CPU M0,M1 electric signal you defined.
for example:
M0 = 0&&M1 = 0 =>little endian
M0 = 1&&M1 =1 =>big endian
else
default endian and the default endian usually is little endian.
If you want more information,pls referrence to your CPU manual.
与大端存储格式相反,在小端存储格式中,字数据的低字节存储在高地址中,而字数据的高字节存储在低地址中。
引用: 引用 9 楼 veabol 的回复:
0x45+0x43+0x45+0x43+0xF0+0x67+0x0A+0x80=0x2F1.
这不就是dwRecChk=F1 02 00 00 嘛
google了一下,结合自己的博客,理解了!呵呵~~
一如既往的感谢韦伯兄对我的帮助!
谢谢!
还要感谢lightsoure兄对我的帮助,在此一并感谢!
问题基本得到解决,结贴!