本节内容:
首先我们会给出LED灯闪烁的汇编代码,然后把上节遗留下来的内容(即SD卡启动时对映像文件的要求)进行补充,然后给出映像文件生成的源代码。最后我们会介绍Makefile的基本书写格式以及介绍gcc、objcopy、objdump的基本用法,对于汇编指令我不做详细介绍,如果想学一点汇编的同学们还是买一本arm的书认真学一下汇编指令,会汇编指令也就那么几页的内容(其实挺多的QAQ)。
start.S:
在start.S代码中主要实现了4个LED灯的闪烁,这只是一个示例的汇编代码,其实用汇编实现一个复杂的功能是一个费力不讨好的事,因为汇编指令不值得过于纠结,什么都用汇编写那还需要C语言干嘛?实在想纠结汇编的可以通过C语言写出对应的代码,然后一个gcc -S选项即可生成汇编代码。我的硬件情况是这样的,我们的4个LED分别接的是GPJ2[3:0],只要给0即可点亮LED,因此我们这里要做的就是把GPJ2CON配置为输出模式,然后设置对应位为0点亮LED,设置对应为为0则关闭LED,我们现在看看start.S的具体代码:
.global _start
_start:
//GPJ2CON[3:0] set output mode
ldr r1, =0xE0200280
ldr r0, =0x00001111
str r0, [r1]
led_blink:
//set led on => GPJ2DAT[3:0] is low
ldr r1, =0xE0200284
mov r0, #0
str r0, [r1]
bl delay
//set led off => GPJ2DAT[3:0] is off
ldr r1, =0xE0200284
mov r0, #0xF
str r0, [r1]
bl delay
b led_blink
halt:
b halt
delay:
mov r0, #0xD00000
delay_loop:
cmp r0, #0
sub r0, r0, #1
bne delay_loop
mov pc, lr
.end
上面的代码其实就是做了配置GPIO的工作模式(输出),设置全部灯关闭(GPJ2DAT=0xFF),延时,设置全部灯打开(GPJ2DAT=0x00)。
SD卡启动要求:
前面讲过,S5pv210上电时候根据OM[5:0]引脚识别是1st boot是哪个设备,然后把设备的前16K代码拷贝到片内iram中,如果代码有效则执行片内代码。那么问题来了,片内代码怎么样才算有效?芯片规定,程序的前16字节用于一些特别的信息(整个代码的字节大小,代码的校验信息),因此我们生成的映像文件要求是:16字节的头部 + 实际代码,然后把映像文件通过dd命令拷贝到SD卡中,S5pv210的BL0通过校验信息知道我们的程序是否是有误(最怕的就是SD卡没程序,却选择SD卡启动,这时通过校验信息知道SD卡内部数据无效就不会执行SD卡内的“代码”了)。首先我给出程序头的格式:
映像文件的第一个字(4字节)保存的是整个映像文件的大小(我们设置成16K即可),第3个字是用于设置校验信息,校验信息是有生成规则的,S5pv210规定代码中按照4个字节对齐,设置uint32_t cheksum=0,每次把4个字节取出来(假设保存在tmp中),执行cheksum+=tmp,直到所有字节都取出来计算过为止,这时checksum中的值就是我们程序的校验信息,把它保存在映像文件的第三个字的地方即可,最后把start.S编译生成的代码拷贝到整个映像文件的后面即完成镜像文件的制作,这些工作都是由源文件mkv210_image.c完成的期待吗如下所示:
#include
#include
#include
#define BUFSIZE (16*1024)
#define IMG_SIZE (16*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)//使用格式:mkv210_image 编译后的文件名 生成的映像文件的名字
{
printf("Usage: mkbl1
Makefile文件:
gcc 用于编译文件,ld工具用于将多个目标文件连接成一个可执行文件(elf格式),objcoy将elf文件中的可执行代码拿出来保存在一个文件里头(elf格式的文件含有很多调试信息,符号表等,我们要把它干掉),objdump用于将elf文件生成对应的调试文件(其实就是以汇编的形式列出整个文件的代码),makefile文件如下:
led.bin: start.o
arm-linux-ld -Ttext 0x0 -o led.elf $^
arm-linux-objcopy -O binary led.elf led.bin
arm-linux-objdump -D led.elf > led_elf.dis
gcc mkv210_image.c -o mkmini210
./mkmini210 led.bin 210.bin
%.o : %.S
arm-linux-gcc -o $@ $< -c
%.o : %.c
arm-linux-gcc -o $@ $< -c
clean:
rm *.o *.elf *.bin *.dis mkmini210 -f
对于ld工具,-T指定连接的信息,例如 -Tlink.lds表示指定链接文件link.lds,-Ttext 0x0就是说可执行文件的链接地址是0地址处。objcopy的-O表示指定输出文件格式,我们舍值为binary(二进制输出)其中led.elf为输入文件,生成的文件名为led.bin。objdump的-D说的是debug,通过led.elf生成调试文件led_ellf.dis(重定向输出)。