1.很多新手学习都是从s3c2410, s3c2440 作为入门工具,该CPU从位置0x0开始运行,所以代码链接的时候,参数为
arm-linux-ld -Ttext 0x0
但是有的CPU不是这样的,比如LH7A404, 通过xmodem上传代码以后,从0xB0000000开始运行,所以链接应该为:
arm-linux-ld -Ttext 0xB0000000
否则,如果数据放入全局变量,比如字符串作为参数传入函数
fun("Hello");
这个时候你访问字符串的地址就会出错!
2. volatile 定义变量很重要,尤其大家的代码在编译的时候使用了 -O1 或者 -O2 进行优化,嘿嘿,如果变量定义没有使用volatile, 可能就会出现不希望的结果啦!
以后慢慢补充,在开发的时候碰到的问题,希望大家学习的时候少走弯路!
3. 简单的入门,一般是从LED点亮和熄灭开始操作。可能都接触过编写crt0.s and led.c文件,交叉编译环境下通过Makefile进行编译
CROSS=arm-linux-
led.bin:led.c crt0.S
${CROSS}gcc -c -o crt0.o crt0.S
${CROSS}gcc -c -o led.o led.c
${CROSS}ld -Ttext 0x00000000 -g led.o crt0.o -o led.elf
${CROSS}objcopy -O binary -S led.elf led.bin
clean:
rm -f led.bin led.elf *.o
有问题么?
当然有,在进行链接(arm-linux-ld)的时候,led.o 和 crt0.o 顺序很关键,马上想到中国领导排位了:)
${CROSS}ld -Ttext 0x00000000 -g crt0.o led.o -o led.elf
这样才正确,首先调用crt0.o中的函数,也就是_start开始。
可以通过反汇编比较两者的代码:
#arm-linux-objdump -d led.elf
4.常用的Samsung的芯片sc2410/2440,如果从Nand Flash启动,从位置0x0开始,内存位置从0x30000000开始。代码
如果要求从0x3000000位置开始,简单的汇编代码可以运行,因为不会涉及到栈的处理。如果有C代码,就需要注意:
在ctr0.S中,首先建议分配栈,执行:
ldr sp, 0x30001000
其中0x30001000,也可以是其它值:0x30002000, 0x30003000 ...etc.
5.msr,mrs的理解
cpsr 和 spsr是两种状态寄存器,mov, ldr等指令不能操作,只能用msr and mrs.
PSR有32位,每8位代表不同的含义,例如:
cpsr_c [从0-7位]
cpsr_f [从24-31位]
msr cpsr, 0x120000d2
这会改变32位的值
msr cpsr_c, 0xd2
仅仅改变最后8位,其它位不会改变
如果期望进入中断模式,call:
msr cpsr_c, 0xd2
0xd2 = 11010010
低5位 10010就是IRQ中断模式
高3位 110 禁止IRQ,FIQ。