http://www.csdn.net/ http://www.arm.com/zh/ https://www.kernel.org/ http://www.linuxpk.com/ http://www.51develop.net/ http://linux.chinaitlab.com/ http://www.embeddedlinux.org.cn http://bbs.pediy.com/
分类: LINUX
2013-05-30 16:27:26
reset:
ldr sp, = 4*1024 @ SP=4096,设置栈指针,后面会调用C函数,调用C前需要设好栈
bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断复位
bl clock_init @ 设置MPLL,改变FCLK、HCLK、PCLK
bl memsetup @ 设置存储控制器以使用SDRAM
bl copy_steppingstone_to_sdram @ 复制代码到SDRAM中
ldr pc, =on_sdram @ 跳到SDRAM中继续执行
on_sdram:
msr cpsr_c, #0xd2 @ 进入中断模式
ldr sp, =4*1024 @ 设置中断模式栈指针
msr cpsr_c, #0xdf @ 进入系统模式
ldr sp, =0x34000000 @ 设置系统模式栈指针,
bl init_led @ 初始化LED的GPIO管脚
bl timer0_init @ 初始化定时器0
bl init_irq @ 调用中断初始化函数,在init.c中
msr cpsr_c, #0x5f @ 设置I-bit=0,开IRQ中断
ldr lr, =halt_loop @ 设置返回地址
ldr pc, =main @ 调用main函数
如上程序中,由于ARM在各种执行模式下都需要设置各自的栈指针,所以"ldr sp,=xxxx"操作较多。根据ARM的ATPCS规则,对栈的操作属于FD(满递减),即栈指针一直指向栈顶元素,是按地址减小的方向增长的,所以一般将SP设置在地址的最高处。
ldr sp, =4*1024, ldr sp, =4*1024, ldr sp, =0x34000000 ,这几个值的确定与硬件关系很大:
1.在reset中:
ldr sp, =4*1024:在ARM9(S3C2440)中,SRAM有效地址范围为0~4K,所以可以把栈初始指针设置在SRAM的有效地址的最高地址处,当然,如果空间够用,也可以设置小点儿,比如:ldr sp , = 2*1024 。
2.在on_sdram中:
ldr sp, =4096 @ 设置中断模式栈指针
ldr sp, =0x34000000 @ 设置系统模式栈指针,
这是分别设定中断模式和系统模式下的堆栈指针到4096(SRAM的有效地址的最高地址)和0x34000000(从0x30000000开始的64M的SDRAM的最高地址处,此时SDRAM已经初始化,可以使用了)。