准备分析
IRAM的大小96k,其实前两个程序都在这里运行的,程序都小于16K。要实现的是从把IRAM从的前16k从IRAM的起始地址0xD0020000拷贝到0xD0024000 处,调用main。堆栈指针设置到了0xD003_7D80处。程序的链接地址是0xD0024010.用图表示如下。本程序只涉及到IRAM,重点为在于重定向。
资源工具
同《 》
着手写程序
start.S中的代码拷贝很重要,Makefile中的链接地址很重要。
- @******************************************************************************
- @ File:start.S
- @ 功能:启动代码,设置栈,拷贝16k到0xd0020000处
- @******************************************************************************
- .text
- .global _start
- _start:
- ldr sp, =0xD0037D80 @ 设置栈,以便调用c函数
- adr r0, _start @ 重定位
- @ _start当前所位于的地址:0xd0020010 (前边放有16bit的头信息)
- ldr r1, =_start @ _start的链接地址:0xd0024010
- ldr r2, =0xd0028000 @ 0xd0028000 = 0xd0024000 + 0x4000(16k)
- cmp r0, r1
- beq run_on_dram
- copy_loop:
- ldr r0, =0xd0020000 @ 源 起始地址
- ldr r1, =0xd0024000 @ 目的 起始地址
- 1:
- ldr r3, [r0], #4 @ 源
- str r3, [r1], #4 @ 目的
- cmp r1, r2
- bne 1b
- run_on_dram:
- ldr pc, =main @ 跳转
- halt:
- b halt
- /******************************************************************************/
- /* File:main.c
- /* 功能:LED闪烁
- /******************************************************************************/
- #define GPJ2CON (*(volatile unsigned long *) 0xE0200280)
- #define GPJ2DAT (*(volatile unsigned long *) 0xE0200284)
- // 延时函数
- void delay(unsigned long count)
- {
- volatile unsigned long i = count;
- while (i--)
- ;
- }
- void main() //LED 闪烁
- {
- GPJ2CON = 0x00001111; // 配置引脚
- while(1) // 闪烁
- {
- GPJ2DAT = 0; // LED on
- delay(0x100000);
- GPJ2DAT = 0xf; // LED off
- delay(0x100000);
- }
- }
Makefile:
- link.bin: start.o main.o
- arm-linux-ld -Ttext 0xD0024010 -o link.elf $^
- arm-linux-objcopy -O binary link.elf link.bin
- arm-linux-objdump -D link.elf > link_elf.dis
- gcc mkv210_image.c -o mkv210
- ./mkv210 link.bin 210.bin
- %.o : %.S
- arm-linux-gcc -o $@ $< -c
- %.o : %.c
- arm-linux-gcc -o $@ $< -c
- clean:
- rm *.o *.elf *.bin *.dis mkv210 -f
下载运行
同《 》
运行调试
程序简单,运行正常。
遗留问题
1.无
原文:http://blog.csdn.net/kangear/article/details/8993247