210学习日记(6)_独立日

210学习日记(6)

--独立日

写了这么久的S5PV210的裸板程序了,每次编译完成后,生成的bin文件总是要经过mktiny210spl.exe(u-boot生成的)重新生成一个新的bin文件,而该bin文件只比旧的bin文件多出四行信息(Tiny210学习日记(2)中有讲过),也就是说,该四行信息是mktiny210spl.exe帮我们写的,所以我们没有真正的独立,没有真正的从头开始写程序。

但是,出于好奇,我今天必须要揭开mktiny210spl.exe的神秘面纱,实现真正的独立!!

尝试一:

在在Tiny210学习日记(2)中有讲到,IROM从外部存储器中拷贝到IRAM中的代码的前16字节不能够是真正的代码,而应该是头部信息,排列格式如下:

---------------------------------------------

0x0地址:BL1 size

---------------------------------------------

0x4地址:必须设置为0 (是规定)

---------------------------------------------

0x8地址:CheckSum

---------------------------------------------

0xc地址:必须设置为0 (是规定)

---------------------------------------------

IROM需要前16字节是头部信息,那我给你头部信息就是,该怎么做呢?按照对信息的强制要求,我做了以下尝试,在start.s的开头添加了以下代码:

.word 0x4000     @规定0x0地址存放要拷贝的大小,那我就给你大小,就16K(最多拷贝16K)

.word 0x0     @规定0x4地址存放0,那我给你0

.word ??      @规定0x8地址存放CheckSum,那么CheckSum该是多少呢?

.word 0x0        @规定0xc地址存放0,那我给你0

在添加代码的时候,出现了疑问,就是CheckSum该是多少?是一个固定值吗?网上收索了大量资料后,最终得出CheckSum的计算公司如下(用一C程序来描述)

#define uBlAddr   直接编译出的bin文件的开始地址

unsigned int count;

unsigned int dataLength; /* 用于指明要拷贝数据的大小,即BL1 size */

unsigned char buf; /* 用于存放临时数据 */

unsigned int checksum; /* 我们要计算的结果,checksum */

for(count=0;count< dataLength;count+=1) 

    buffer = (*(volatile unsigned char*)(uBlAddr+count)); 

    checksum = checksum + buffer; 

}

最终发现,checksum是动态生成的,是可变的,所以直接导致尝试一以失败告终!!!

继续查阅资料......

尝试二:

查了很久的资料,最终想起,最好的资料就是u-boot了,这个工具不是u-boot生成的吗?那么里面肯定有它的源码,一搜索,一提炼,果然,发现它的代码如下:

这是一个属于应用程序的工具了,一看这个代码,我才发现我大一学习的C函数中关系文件操作的知识全部忘光了,不过在查阅资料以后,我还是给出了详细的注释......

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#define SEEK_SET        0 /* 文件开头的标记 */

#define SEEK_CUR 1 /* 当前位置的标记 */

#define SEEK_END 2 /* 文件末尾的标记 */

#define BUFSIZE                 (24*1024)

#define IMG_SIZE                (24*1024)

#define SPL_HEADER_SIZE         16

#define SPL_HEADER              "S5PC110 HEADER  "

int main (int argc, char *argv[])

{

FILE *fp;    /* 定义一个文件指针 */

char *Buf, *a;

int BufLen;

int nbytes, fileLen;

unsigned int checksum, count;

int i;

if (argc != 3) /* 如果参数个数错误,打印帮助信息 */

{

/*   应用工具时,格式必须是 ./mktiny210spl.exe old.bin new.bin    */

printf("Usage: mkbl1 <source file> <destination file>\n");

return -1;

}

BufLen = BUFSIZE;

Buf = (char *)malloc(BufLen); /* 动态分配一段24k的内存空间 */

if (!Buf) /* 分配失败,将返回0 */

{

printf("Alloc buffer failed!\n");

return -1;

}

memset(Buf, 0x00, BufLen); /* 将上面分配的空间清零 */

fp = fopen(argv[1], "rb"); /* 以读二进制的方式打开没有头部信号的old.bin文件 */

if( fp == NULL)

{

printf("source file open error\n");

free(Buf); /* 如果打开失败,释放掉原来分配的内存,否则会造成内存泄漏 */

return -1;

}

fseek(fp, 0L, SEEK_END); /* 让文件位置指针指向文件末尾,便于下行的统计大小的操作 */

fileLen = ftell(fp); /* 用于得到文件位置指针当前位置相对于文件首的偏移字节数,即文件大小*/

fseek(fp, 0L, SEEK_SET); /* 让文件位置指针指向文件开始 */

/* 如果old.bin文件的大小小于规定的最大大小,则count等于该文件的大小,否则等于最大大小 */

count = (fileLen < (IMG_SIZE - SPL_HEADER_SIZE)) ? fileLen : (IMG_SIZE - SPL_HEADER_SIZE);

memcpy(&Buf[0], SPL_HEADER, SPL_HEADER_SIZE); /* 拷贝16字节的数据到Buf中,即初始化头 部信息的位置 */

nbytes = fread(Buf + SPL_HEADER_SIZE, 1, count, fp); /* 将编译生成的old.bin文件拷贝到buf中,紧 接着头部信息开始拷贝 */

if ( nbytes != count ) /* 返回值等于拷贝的元素的个数 */

{

printf("source file read error\n"); /* 如果个数和实际的不想等,则失败 */

free(Buf); /* 释放内存 */

fclose(fp); /* 关闭文件 */

return -1;

}

fclose(fp); /* 关闭文件 */

/* 以下三行,用于动态生成checksum,公式见上面的尝试一 */

a = Buf + SPL_HEADER_SIZE;

for(i = 0, checksum = 0; i < IMG_SIZE - SPL_HEADER_SIZE; i++)

checksum += (0x000000FF) & *a++;

/* checksum写入buf的第三个字节处,即该是checksum的位置处 */

a = Buf + 8;

*( (unsigned int *)a ) = checksum;

fp = fopen(argv[2], "wb"); /* 以二进制写的方式创建一个新的二进制文件 */

if (fp == NULL)

{

printf("destination file open error\n");

free(Buf); /* 释放内存 */

return -1;

}

a = Buf; /* 指向内存的首地址 */

nbytes = fwrite( a, 1, BufLen, fp); /* buf中的数据写入新创建的bin文件 */

if ( nbytes != BufLen ) /* 返回值等于写入的元素的个数 */

{

printf("destination file write error\n");

free(Buf); /* 释放内存 */

fclose(fp);/* 关闭文件 */

return -1;

}

free(Buf); /* 释放内存 */

fclose(fp);/* 关闭文件 */

return 0;

}

以上的实现过程就是mktiny210spl.exe的真实面目。接下来就是该怎么生成这个工具了,步骤如下:

1).新建一个文件,命名为wy_mktools.c(毕竟花费了这么久的时间来学习它,所以就取属于自己的名字了)

2).将尝试二中的代码录入wy_mktools.c;

3).编译生成wy_mktools.exe(Makefile的内容如下)

wy_mktools.exe: wy_mktools.c

gcc  wy_mktools.c  -o  wy_mktools.exe

到此,自制小工具终于成功了,独立日也从此到来。以后请执行./wy_mktools.exe old.bin new.bin吧!!

注意:

1.我用的是第一个流水灯实验做的测试,用于测试的代码放到了"Tiny210学习日记_代码"目录下了,名为"5_water_led_independent",当然,以后每个程序都是用的wy_mktools.exe!!

2.自制工具的相关代码,以及Makefile都放到了"Tiny210学习日记_代码"目录下了,名为"wy_mktools"

3.该工具有点问题,但是现在能够使用。我会在后面讲问题出在哪里,和如何修改!!

注:

如有问题,请到韦东山LINUX视频讨论群里面,我们一起讨论学习,或者加我QQ317312379

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值