更正《Mini210S裸机程序开发指南.pdf》以下信息:
“从三星提供的S5PV210 文档《S5PV210_iROM_ApplicationNote_Preliminary_20091126.pdf》
以及芯片手册《S5PV210_UM_REV1.1.pdf》得知,S5PV210 启动时,会先运行内部IROM中的固化
代码进行一些必要的初始化,执行完后硬件上会自动读取NAND Flash 或sd卡等启动设备的前16K
的数据到IRAM中,这16K 数据中的前16byte中保存了一个叫校验和的值,拷贝数据时S5PV210
会统计出待运行的bin 文件中含‘1’的个数,然后和校验和做比较,如果相等则继续运行程序,
否则停止运行。”
其实这16K的数据中还包含了一个文件大小的信息,如下:
Header Info
0x0==>>BL1 size (User write)
0x4==>>Reserved (should be 0)
0x8==>>CheckSum (User write)
0xc==>>Reserved (should be 0)
实验证明,硬件会根据BL1 size 去读取Nand Flash中的数据然后与CheckSum做比较,在《S5PV210_iROM_ApplicationNote_Preliminary_20091126.pdf》
中有写到:BL1 max. size is 16KB. BL2 max. size is 80KB。所以,16K的数据只是说最大是16K,而不是一定要有16K。
实现给BL1 增加头部信息的程序如下,但为配合MiniTools烧写工具,还必须在BL1后面写0,保证16K的大小,否则无法烧录!
/**********************************************************
文件名:AddFilesizeChecksum.c
版 本:1.0.1-2013.10.22.003
设 计:Zhu Yundong
功 能:给小于16K-16bytes的BIN文件增加头部信息
编 译:gcc <文件名> -o <执行程序名>
用 法:<执行程序名> <源文件> <目标文件>
***********************************************************/
#include "stdio.h"
FILE *SourceFile;//源文件指针
FILE *destinationFile;//目标文件指针
void WriteFile(unsigned long FileData)//写4个字节到目标文件
{
unsigned char i;
for(i=0;i<4;i++)
{
fputc((FileData>>(i*8))&0xff,destinationFile);
}
}
int main (const char command,const char *input[3])
{
unsigned char ch;
unsigned long i;
unsigned long Filesize;
unsigned long Checksum;
unsigned long FileData;
if (command!=3)//确认接收到的命令参数是否等于3
{
printf("Usage: <Executable name> <source file name> <destination file name>\n");
return -1;
}
if((SourceFile=fopen(input[1],"rb"))==NULL)//确认源文件是否正常打开
{
printf("Open source file error!\n");
return -1;
}
fseek(SourceFile, 0L, SEEK_END);//重定位流上的文件指针到结束位置
Filesize=ftell(SourceFile);//获取源文件大小
fseek(SourceFile, 0L, SEEK_SET);//重定位流上的文件指针到起始位置
if(Filesize>16*1024-16||Filesize==0)//确认源文件大小是否符合(大于0并且小于16K-16bytes)
{
if(Filesize==0)printf("Filesize 0 bytes!\n");
else printf("Filesize > 16368 bytes(16K-16B)!\n");
return -1;
}
Checksum=0;
for(i=0;i<Filesize;i++)//计算源文件Checksum
{
ch=fgetc(SourceFile);
Checksum+=ch;
}
if((destinationFile=fopen(input[2],"wb"))==NULL)//确认目标文件是否正常打开
{
printf("Open the destination file error!\n");
return -1;
}
WriteFile(Filesize+16);//向目标文件写入文件大小信息(文件大小:0x00-0x03)
WriteFile(0x00);//向目标文件写入文件大小信息(保留清零:0x04-0x07)
WriteFile(Checksum);//向目标文件写入文件Checksum(Checksum:0x08-0x0B)
WriteFile(0x00);//向目标文件写入文件Checksum(保留清零:0x0C-0x0F)
fseek(SourceFile, 0L, SEEK_SET);//重定位流上的文件指针到起始位置
for(i=0;i<Filesize;i++)//将源文件写入目标文件(地址范围:0x010-3FFF)
{
ch=fgetc(SourceFile);
fputc(ch,destinationFile);
}
/*************************************************************************************************/
///////////////////////////////////////////////////////////////////////////////////////////////////
for(i=0;i<16*1024-16-Filesize;i++)//为了配合烧写器,必须将多余空间清零(地址范围:Filesize-3FFF)
{
ch=0x00;
fputc(ch,destinationFile);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
/*************************************************************************************************/
fclose(SourceFile);//关闭源文件
fclose(destinationFile);//关闭目标文件
return 0;
}