完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
file:///C:UserswdxlAppDataRoamingTencentUsers1154919889QQWinTempRichOle_}D(VA%_P7]XE`5OIE)T6YY.jpg在复制代码到SDRAM以后,CPU内部的SRAM也有和SDRAM一模一样的代码了,为什么执行ldr pc,=on_sdram就跳到SDRAM,他怎么知道跳哪里呢?CPU内部不也有on_sdram这段代码吗?
|
|
相关推荐
4个回答
|
|
我来自己解答一下:做个记录,以免以后还不记得。
arm在Nand flash启动模式下启动时系统会将Nand flash中的前4KB代码拷贝到SRAM(也就是Steppingstone中),由SRAM配置中断向量表和完成Nand flash访问的必要初始化,然后将Nand flash中的全部程序代码拷贝到SDRAM中,最后由SRAM跳转到SDRAM,然后程序就正常执行了。 如下代码: .extern main .text .global _start _start: b reset reset: ldr sp,=4096 bl disable_watch_dog bl clock_init bl memsetup bl copy_steppingstone_to_sdram ldr pc,=on_sdram on_sdram: msr cpsr_c,#0xdf ldr sp,=0x34000000 ldr lr,=halt_loop ldr pc,=Main halt_loop: b halt_loop 借此来分析整个流程: (1)由于arm执行reset之后pc会被清零,也就是reset中断的中断入口地址,因此,第一条指令就是b reset,跳转到reset中断处理函数。 (2)由于这里硬件配置都是C语言来完成的,而且我们的初始代码比较小,完全不会超出4KB,因此可以在SRAM使用堆栈,故将SP设置为4096,以提供C运行环境 (3)接下来的3个bl分别完成了关闭看门够定时器,配置时钟信号和存储器配置的工作,第四个bl是将SRAM的4KB空间内的代码拷贝到了SDRAM中。(备注:因为此处代码量小全部在4KB范围所以只要将stepping stone中的代码拷贝到sdram中即可,但当代码量大于4KB的时候就要从NAND flash中将所有代码拷贝到sdram中。这个过程实质就是讲存储在NAND flash中的所有代码拷贝到sdram,然后跳转到sdram中去执行) (4)接下来的ldr句将pc赋值为on_sdram的地址,实现了从SRAM到SDRAM的跳转(具体原理后面分析) (5)on_sdram中切换到了了系统模式然后分配了系统模式堆栈,将链接寄存器设置为halt_loop然后就跳转到了SDRAM中的Main 为什么ldr pc,=on_sdram就实现了从SRAM到SDRAM的跳转呢? bl指令跟ldr指令在执行过程中的区别: B指令是相对跳转指令,B 指令是最简单的跳转指令。一旦遇到一个 B 指令,ARM 处理器将立即跳转到给定的目标地址,从那里继续执行。注意存储在跳转指令中的实际值是相对当前PC 值的一个偏移量,而不是一个绝对地址,它的值由汇编器来计算(参考寻址方式中的相对寻址)。它是 24 位有符号数,左移两位后有符号扩展为 32 位,表示的有效偏移为 26 位(前后32MB 的地址空间),同样的,BL、BX都是相对跳转。 LDR伪指令是将第二操作直接赋值给第一操作数,当执行ldr pc,=Main时是将Main的绝对地址赋值给了PC。 2440的开发板有SRAM和SDRAM,SRAM是从地址0x00000000开始的4KB内存空间,SDRAM是从0x30000000开始的64M空间。 无论用ADS编译还是用arm-linux-gcc编译都会将代码链接到0x30000000以后(也就是SDRAM中),ADS用户可以通过查看ADS的工程配置,其中有项配置是RO起始地址是0x30000000,linux用户在链接时需要用-T指定代码的其实地址为0x30000000。 根据编译原理,在链接阶段程序中函数的地址就已经确定了,也就是说函数的实际地址都在0x30000000之后,而程序的入口函数也就是这里的_start的地址就是0x300000000,其他函数都会大于这个数。 但是由于arm上电后系统会将Nand flash的前4KB代码拷贝到SRAM中,也就是_start函数开始的4KB指令将被拷贝到SRAM中执行,根据上例,在0x00000000处执行的指令就是“b reset”,由于b是相对跳转,是在当前pc值的基础上加减某个数而跳转到将要执行的代码处,因此,pc加减该数之后将到达reset函数的位置,故reset函数不能写到4KB之外的空间中,否则arm的启动将会失败,同样的,接下来的几个bl都是执行的相对跳转,所以都相对当前pc进行的跳转,由于Nand flash总共只有64M的空间,所以相对跳转是不可能会跳转到SDRAM的,因为跳转到SDRAM至少要发生0x30000000的跳转,而这个相对位移远远大于64M。 ldr pc,=Main是将Main函数的实际地址赋值给pc,而Main的实际地址是在0x30000000之后,这样,就从SRAM跳转到了SDRAM。 |
|
|
|
66666666666666666666666666
|
|
|
|
SRAM的起始地址并不是0x00000000,而是0x40000000,NOR Flash的起始地址才是0x00000000.NAND Flash启动时把NAND Flash前4K拷贝到SRAM中,并将SRAM前4K映射到0x00000000起始地址处,4K后的地址是NAND Flash中的。NOR Flash启动时不需要进行地址映射,此时SRAM还是0x40000000起始地址。
|
|
|
|
挺详细的 厉害
|
|
|
|
只有小组成员才能发言,加入小组>>
197个成员聚集在这个小组
加入小组为什么点亮LED的例子放在NORFlash上跑会出现奇怪的现象?
2150 浏览 6 评论
1959 浏览 5 评论
韦东山老师推出的《玩转ARM裸机实战》课程将帮你以上问题一扫而光!
4517 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-15 03:21 , Processed in 1.088312 second(s), Total 84, Slave 64 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号