smart210开发板裸机bin文件起始地址设置

一、平台代码

1、使用的平台

我使用友善之臂公司出品的smart210平台,cpu是s5pv210。在裸机开发时,用usb线烧写bin文件到内存中直接运行。

2、使用的代码

为了尽量排除其它因素的干扰,使用最简单的led跑马灯代码。该程序由两部分组成:start.S和led.c,代码如下:

start.S

.global _start
.global main

_start:
    bl main    
over:
    b over

led.c



#define GPJ2CON    (*(volatile unsigned int *)0xE0200280)
#define GPJ2DAT    (*(volatile unsigned int *)0xE0200284)

void led_init(void)
{
      GPJ2CON=0x1111;  
      GPJ2DAT=0xf;
}
void delay(unsigned int n)
{
    while(n--);
}

int main(void)
{
    led_init();
    unsigned int i=0;
    while(1)
    {
        GPJ2DAT=~(1<<(i%4));
        i++;        
        delay(0x100000);
    }   

}

3、编译指令

以下是我用的makefile文件,交叉编译工具用的是开发板自带的arm-linux-gcc。

name=led
obj=start.o led.o

$(name)new.bin:$(name).bin
    gcc mkv210_image.c -o mkv
    ./mkv $^ $@

$(name).bin:$(name).elf
    arm-linux-objcopy -O binary $^ $@
    arm-linux-objdump -D $^ >$(name).dis

$(name).elf:$(obj)
    arm-linux-ld -Ttext=0x20000000 $^ -o $@
.S.o:  
    arm-linux-gcc -c $<
.c.o: 
    arm-linux-gcc -c $<

clean:
    rm *.o *.elf *.bin -f

三、试验

1、正常编译

查看反汇编代码前面几句如下:

20000000 <_start>:
20000000:   eb000020    bl  20000088 <main>

20000004 <over>:
20000004:   eafffffe    b   20000004 <over>

20000008 <led_init>:
20000008:   e52db004    push    {fp}        ; (str fp, [sp, #-4]!)

生成的bin文件前面部分如下

20 00 00 EB FE FF FF EA  04 B0 2D E5 00 B0 8D E2

可以看到bin文件里面是纯粹的语句,没有任何的地址信息。
烧写到内存后,cpu直接跳转到0x20000000的地址处运行,跑马灯是正常的。

2、仅用c文件编译

start.S文件仅仅用来跳转,那就把它去掉吧。仅仅留c文件。
编译后的elf文件和bin文件分别如下:

Disassembly of section .text:

20000000 :
20000000:   e52db004    push    {fp}        ; (str fp, [sp, #-4]!)
20000004:   e28db000    add fp, sp, #0
20000008:   e59f301c    ldr r3, [pc, #28]   ; 2000002c 
04 B0 2D E5 00 B0 8D E2  1C 30 9F E5 1C 20 9F E5 

烧写到板子,无法运行。
查看编译输出,有一条警告:

arm-linux-ld: warning: cannot find entry symbol _start; defaulting to 20000000

入口地址被设为20000000,而那里是led_init的函数,因此无法运行。

3、设定入口地址

将 arm-linux-ld -Ttext=0x20000000 o @加上 –entry=main
用readelf -a led.elf分析文件,结果如下

入口点地址:              0x20000080
程序头起点:              52 (bytes into file)

入口点已正确设置,再看bin文件:

04 B0 2D E5 00 B0 8D E2  1C 30 9F E5 1C 20 9F E5

没有任何改变。烧写后仍然不能成功运行。
看来是objcopy的问题了。

4、增加objcopy选项

objcopy里有一个–set-start=val的选项,加上这个选项后,bin文件没有任何改变。查看选项说明:Not all object file formats support setting the start address. 好吧。看来是不支持。

5、修改minitools的地址

将下载和运行地址改为20000080,如下
smart210开发板裸机bin文件起始地址设置_第1张图片

烧写后仍无法运行。

6、重新排列函数的顺序

将main函数放在最上部,将其它函数放在后面,这样main函数的地址就是0x20000000。编译烧写后运行成功。

结论

开发板默认从bin文件的起始处开始运行,无法设定特定的入口地址,如果要将某个函数设为入口,必须重新排列顺序,将函数放在最开始的位置。

你可能感兴趣的:(嵌入式)