bootloader---13.将程序搬到sdram中

原创 2016年08月29日 13:55:31
  初始化好了sdram之后,下面就试一下把sram中的前4k搬到sdram中并跳转到链接地址处执行,这样就不用老是担心写的代码是不是位置无关(PIC)的了,下面是程序的所有文件。

点击(此处)折叠或打开

  1. root@ubuntu:~/myboot# tree
  2. .
  3. ├── main.c
  4. ├── Makefile
  5. ├── sdram.c
  6. ├── start.S
  7. └── u-boot.lds
  8. 0 directories, 5 files

1. start.S

点击(此处)折叠或打开

  1. .text
  2. .global _start
  3. _start:
  4.     /*关闭看门狗*/
  5.     ldr r0, =0x53000000    
  6.     mov r1, #0x0
  7.     str r1, [r0]

  8.     /*初始化系统时钟: FCLK=400M HCLK=100M PCLK=50M */
  9. #define COCKTIME    0x4C000000    
  10. #define MPLLCON        0x4C000004
  11. #define UPLLCON        0x4C000008
  12. #define CLKCON        0x4C00000C
  13. #define CLKSLOW        0x4C000010
  14. #define CLKDIVN     0x4C000014
  15. #define CAMDIVN     0x4C000018
  16.     /*FCLK:HCLK:PCLK=1:4:8*/
  17.     ldr r0, =CLKDIVN
  18.     mov r1, #0x05
  19.     str r1, [r0]

  20.     mrc p15, 0, r0, c1, c0, 0
  21.     orr r0, r0, #0xc0000000
  22.     mcr p15, 0, r0, c1, c0,0

  23.     /*MPLL=(2*m*Fin)/(P*(1<<s)), m="(MDIV+8)," p="PDIV+2" s="SDIV*/
  24.     ldr r0, =MPLLCON
  25.     ldr r1, =((0x5C<<12)|(0x01<<4)|(0x01))
  26.     str r1, [r0]
  27.     
  28.     ldr r0, =0x10000
  29. 1:
  30.     sub r0, r0, #1
  31.     bne 1b

  32.     /*UPLL=(m*Fin)/(P*(1<<s)), m="(MDIV+8)," p="(PDIV+2)," s="SDIV*/
  33.     ldr r0, =UPLLCON
  34.     ldr r1, =((0x10<<12)|(0x01<<4)|(0x01))
  35.     str r1, [r0]

  36.     ldr r0, =0x10000
  37. 1:
  38.     sub r0, r0, #1
  39.     bne 1b
  40.     
  41.     /*设置栈,因为下一步要调用c函数init_sdram*/
  42.     ldr sp, =1024*4
  43.     bl init_sdram

  44.     /*sdram初始化好之后,重新设置栈到内存 0x33d80000+128k*/
  45.     ldr sp, =0x33dA0000
  46.     
  47.     /*复制 steppingstone 到内存: r0=src r1=dest r2=size=4k*/
  48.     mov r0, #0x0
  49.     ldr r1, =0x33d80000
  50.     ldr r2, =1024*4

  51. copy_loop:
  52.     ldmia     {r3-r10}        /* copy from source address [r0] */
  53.     stmia     {r3-r10}        /* copy to target address [r1] */
  54.     cmp    r0, r2                    /* until source end addreee [r2] */
  55.     ble    copy_loop    
  56.     
  57.     /*跳转到main中 此处bl与ldr跳转不一样*/
  58.     /*bl main*/
  59.     ldr pc, _main
  60. loop:
  61.     b loop
  62. _main: .word main
2. main.c

点击(此处)折叠或打开

  1. #define GPBCON (*(volatile unsigned int *) 0x56000010)
  2. #define GPBDAT (*(volatile unsigned int *) 0x56000014)

  3. static inline void delay (unsigned long loops)
  4. {
  5.     __asm__ volatile ("1:\n"
  6.             "subs %0, %1, #1\n"
  7.             "bne 1b":"=r" (loops):"0" (loops));
  8. }
  9. /* 闪灯测试: sram快 sdram稍慢 */
  10. void main(void)
  11. {
  12.     int i = 1;
  13.     GPBCON = 0x15400;
  14.     while(1)
  15.     {
  16.         GPBDAT = 0x7FF&(~i<<5);
  17.         i *= 2;
  18.         if(16==i)
  19.             i = 1;
  20.         delay(400000);
  21.     }
  22.     return ;
  23. }
3. sdram.c 与 u-boot.lds都无改动
4. Makefile 中 OBJS :=  start.o main.o sdram.o
5. 把start.S中的ldr pc, _main 改为 bl main, 编译后分别烧到板子中,可以发现程序运行在sram比sdram中灯闪烁的速度快一些。
把这两个程序反汇编进行比较:

点击(此处)折叠或打开

  1. root@ubuntu:~/myboot# diff u-boot.dis_sdram u-boot.dis_sram 
  2. 44c44
  3. < 33d80084:    e59ff000     ldr    pc, [pc, #0]    ; 33d8008c <_main>
  4. ---
  5. > 33d80084:    eb000008     bl    33d800ac
ldr    pc, [pc, #0] 
把当前pc地址处的值赋给pc,当前pc=(0x33d80084+8)-0x33d80000=0x008C, 0x008C处的值为0x33d800ac,所以执行这条指令后pc指向了0x33d800ac,也就是内存中main函数的入口地址。

33d80084:   eb000008    bl  33d800ac
以当前pc地址进行相对跳转,当前pc=(0x33d80084+8)-0x33d80000=0x008C,根据跳转的指令格式可知跳转到的地址为:0x8C+8<<2=0xAC,执行这条指令的后pc指向了0xAC, 还是在sram中的main函数的入口地址。


注意:1. 虽然反汇编文件中的地址都是0x33d80000,但是实现上程序并没有运行在0x33d80000,而是运行在0x0地址,所以在计算时要减去0x33d80000.同时虽然地址不吻合,但是地址里面的值却是正确的,可以放心用。
2. arm9五级流水,pc地址要加8,至于为什么可以看下面:
3. eb000008 转为二进制
   1110 1011 0000 0000 0000 0000 1000

   1110: always
   101:
   1:   说明这是一条bl指令
   0000 0000 0000 0000 1000: word 对齐,最右边两位总是0,所以省略,计算时需要向左移两位,即乘以4。
   
出自《ARM7TDMI-S Data Sheet》chapter_4 “arm instruction set”   


版权声明:本文为博主原创文章,转载请注明出处。

F2812程序从Flash搬到RAM中运行(调试过程)

芯片名称:TMS320F2812    编译器版本:CCS2.2 F2812程序在Flash中运行速度较慢,对时间敏感的程序需要从Flash搬到RAM中运行,有两种方法: 1 部分程序搬运   ...
  • u013315519
  • u013315519
  • 2013年12月30日 17:03
  • 976

s3c2440中断程序(烧录到NORFlash,运行在SDRAM中)

将系统启动时寻找的八个跳转指令写入一个文件,将其加载地址和运行地址都设为0x0,即加载和运行都在NORFlash的0x0。而其余的程序部分:关闭看门狗,设置堆栈,初始化SDRAM,搬移程序到SDRAM...
  • passerby_unnamed
  • passerby_unnamed
  • 2016年04月04日 10:38
  • 856

FPGA学习之路---SDRAM讲解

如果对SDRAM原理以及时序不是很了解的朋友,推荐看一下如下这篇文章: SDRAM-高手进阶,终极内存技术指南——完整进阶版 ***********************************...
  • lusics
  • lusics
  • 2016年12月14日 20:58
  • 1614

SDRAM的读写

SDRAM的读/写时序与突发长度数据输出(读)在选定列地址后,就已经确定了具体的存储单元,剩下的事情就是数据通过数据I/O通道(DQ)输出到内存总线上了。但是在CAS发出之后,仍要经过一定的时间才能有...
  • liukun321
  • liukun321
  • 2010年05月18日 19:15
  • 5322

记录一次stm32F429 IAP跳转到SDRAM内执行程序的DEBUG过程

stm32在sdram内运行用户程序
  • lrmlrm
  • lrmlrm
  • 2016年05月12日 11:20
  • 3619

S3C2440 跳到 SDRAM 中执行程序

---总结于韦东山老师书籍       从Nandflash启动CPU时,CPU会通过内部的硬件将Nandflash开始的4KB数据复制到为Steppingstone的4Kb的内部RAM...
  • yikai2009
  • yikai2009
  • 2012年12月02日 19:48
  • 2252

SDRAM的数据在掉电后可以保存多久?

你电脑上的内存SDRAM条取下来,多久以后,内存的数据会消失? 大多数的人认为是几秒钟....
  • s8848
  • s8848
  • 2015年02月10日 15:12
  • 2700

S3C2440 SDRAM寄存器初始化设置

板子是s3c2410,使用两片容量为32MB、位宽16bit的EM63A165TS-6G芯片拼成容量为64M、32bit的SDRAM存储器。根据2410datasheet,要使用SDRAM需配置13个...
  • qq_21792169
  • qq_21792169
  • 2015年11月21日 15:12
  • 14629

S3C2440 nand sdram启动时代码的运行转移过程

S3C2440的boot code能够在外部的nand flash内存中执行。为了支持nand flash 的boot 引导,S3C2440有一个内部的SDRAM缓存称为“Steppingstone”...
  • ltt305210390
  • ltt305210390
  • 2013年07月05日 15:17
  • 850

将FPGA(Nios软件部分)程序放在SDRAM里面跑

加了Nios并在上面跑uCOS的时候,nios里面的onchip memory已经无法满足程
  • winniezheng
  • winniezheng
  • 2014年04月25日 13:40
  • 1695
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:bootloader---13.将程序搬到sdram中
举报原因:
原因补充:

(最多只允许输入30个字)