一个bin 文件在存储上是按下面的结构存储的
组成:标记(7)+Image开始地址(1)+Image长度(1)
记录0地址+记录0长+记录0校验和+记录0内容(文件内容)
记录1地址+记录1长+记录1校验和+记录1内容(文件内容)
......
最后一条记录是表示结束,Start = 0x00000000, Length = 0x8C072C3C是StartUp地址, Chksum = 0x00000000
bin 文件的头部(不包括记录)可以用下面的结构表示
struct BinFile{
BYTE signature[7]; // = { ''B'', ''0'', ''0'', ''0'', ''F'', ''F'', ''/a'' }
DWORD ImageStart
DWORD ImageLength
};
一般xipkernel.bin,nk.bin 都符合正常bin文件格式,包含记录开始0,1,2 记录为特殊记录,2做为cece的标记,其后4byte表示 TOC地址(指向ROMHDR结构的数据),3记录开始都是文件记录,
———但是,我们实际用到却是nk.nb0文件,这个文件才是和文件系统帮顶起来的
以下是解码程序:
S16 EBOOT_AnlayBINFile(U32 uiBINStartAddr, U32 *uiNb0FileSize)
{
U32 ImageStartAddr = 0;
U32 ImageLength = 0;
U8 acBinFileSign[10] = {0};
U32 uiAddr = 0;
U32 uiLength = 0;
U32 uiCheck = 0;
S16 nResult = 0;
U32 i = 0;
//判断是否是NK.bin文件
memcpy(acBinFileSign, (void *)uiBINStartAddr, 7);
if(strcmp(acBinFileSign, BINFILE_SIGN))
{
return ERR_FAIL;
}
//得到镜像的起始地址和总的长度
uiBINStartAddr += 7;
ImageStartAddr = EBOOT_GetBinFile32BitData((U8 *)(uiBINStartAddr));
uiBINStartAddr += 4;
ImageLength = EBOOT_GetBinFile32BitData((U8 *)(uiBINStartAddr));
uiBINStartAddr += 4;
//清空保存解析NK.BIN文件缓存的数据为0
uiAddr = IMAGE_START_ADDR;
for(i = 0; i < ImageLength; i += 4)
{
*(U32 *)(uiAddr + i) = 0x00000000;
}
while(1)
{
uiAddr = EBOOT_GetBinFile32BitData((U8 *)(uiBINStartAddr));
uiBINStartAddr += 4;
uiLength = EBOOT_GetBinFile32BitData((U8 *)(uiBINStartAddr));
uiBINStartAddr += 4;
uiCheck = EBOOT_GetBinFile32BitData((U8 *)(uiBINStartAddr));
uiBINStartAddr += 4;
nResult = EBOOT_JudgeRecordData(uiLength, (U8 *)(uiBINStartAddr), uiCheck);
if(nResult == ERR_FAIL)
{
return ERR_FAIL;
}
memcpy((void *)(uiAddr - 0x50000000), (void *)uiBINStartAddr, uiLength);
uiBINStartAddr += uiLength;
if((uiAddr + uiLength) == (ImageStartAddr + ImageLength))
{
break;
}
}
*uiNb0FileSize = ImageLength;
return ERR_OK;
}
U32 EBOOT_GetBinFile32BitData(U8 *uiBinAddr)
{
return ((uiBinAddr[0]) | (uiBinAddr[1] << 8) | (uiBinAddr[2] << 16) | (uiBinAddr[3] << 24));
}
S16 EBOOT_JudgeRecordData(U32 uiLength, U8 *pData, U32 uiCheck)
{
U32 i = 0;
U32 iCheckData = 0;
//获取该记录数据的校验码
for(i = 0; i < uiLength; i++)
{
iCheckData += pData[i];
}
//判断该校验码是否正确
if(iCheckData != uiCheck)
{
return ERR_FAIL;
}
return ERR_OK;
}