下面说一下,之前我们写的简单程序,没有用到DDR,只是将程序在6410的8K片内内存中运行,但是如果程序很大,那就不能指望在片内内存中运行我们的程序了。下面就要用到SDRAM,就要涉及到链接地址。
简单的说,一个程序分为下面几个部分:
(1)代码段(text):就是我们所写的代码,指令
(2)数据段(data):有初始值的全局变量或静态变量
(3)Bss段(Bss):未初始化或初始值为0的全局变量或静态变量
分析反汇编文件我们得出:访问全局变量使用的是链接地址来访问的。在系统上电后,系统会自动的把NandFlash中的前8K程序拷贝到片内8K内存当中去,而一个程序要执行,应该位于链接地址。当程序的链接地址不等于当前地址时,就需要重定位,将程序拷贝到相应的链接地址中去执行。
位置无关码:相对跳转指令,不访问全局变量。下面看一下重定位代码:/* relocation */
adrr0, _start@ get _start's current address: 0
ldrr1, = _start @ _start's link address
ldrr2, = bss_start@ bss section's begining link address
cmpr0, r1 @ compare isnot equal
beqclean_bsscopy_loop:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r1, r2
bne copy_loop/* clear bss section */clean_bss:
ldrr0, = bss_start
ldrr1, = bss_end
movr3, #0
cmpr0, r1
ldreqpc, = on_ddr
clean_loop:
strr3, [r0], #4
cmpr0, r1
bneclean_loop
ldrpc, = on_ddr
在分析过程中,我们可以参照反汇编文件来分析!
1.9 Makefile
由于是在Linux下开发,了解Makefile也是很有必要的,下面是本模板的Makefile代码:CC = arm-linux-gcc
LD = arm-linux-ld
AR = arm-linux-ar
OBJCOPY = arm-linux-objcopy
OBJDUMP = arm-linux-objdump
CFLAGS = -Wall -Os -fno-builtin-printfexport CC LD AR OBJCOPY OBJDUMP CFLAGS
objs := start.o time.o sdram.o irq.o led.o
led.bin : $(objs)
$(LD) -Tled.lds -o led_elf $^
$(OBJCOPY) -O binary -S led_elf $@
$(OBJDUMP) -D -m arm led_elf > led.dis
%.o : %.c
$(CC) $(CFLAGS) -c -o $@ $<
%.o : %.S
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f *.dis *.bin *_elf *.o
总结:(待续……)
[1] [2] [3]
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。