代码改变世界

MINI2440-SDRAM

2015-10-20 15:42  Kelvin'sCnBlogs  阅读(349)  评论(0编辑  收藏  举报

目的:Norflash前4K的内容到SDRAM,并且成功点亮LED;

过程:

1.程序(main.c    startup.s    Makefile)

  1.1.main.c 

  
 1 #define GPBCON    (*(volatile unsigned long*)0x56000010)
 2 #define GPBDAT    (*(volatile unsigned long*)0x56000014)
 3 
 4 
 5 #define GPB_OUTPUT 01
 6 #define GPB_CONFIG(IO,CONFIG) (CONFIG << (IO*2))    
 7 
 8 int main()
 9 {
10     
11     GPBCON |=  GPB_CONFIG(5,GPB_OUTPUT) 
12              | GPB_CONFIG(6,GPB_OUTPUT)
13              | GPB_CONFIG(7,GPB_OUTPUT)
14              | GPB_CONFIG(8,GPB_OUTPUT);
15     
16     GPBDAT  =  0X00000000;
17 
18     return 0;
19 }
main.c

   1.2.startup.s 

  
 1 .equ    MEM_CTL_BASE,    0x48000000    
 2 .equ    SDRAM_BASE,        0x30000000
 3 
 4 .text
 5 .global _start
 6 _start:
 7 
 8     bl  disable_watch_dog
 9     bl  sdram_init
10     bl  copy_steppingstone_to_sdram
11         
12     ldr  pc, =on_sdram
13 
14 on_sdram:
15     ldr  sp, =0x34000000
16     bl   main
17 
18 halt_loop:
19     b halt_loop
20 
21 disable_watch_dog:
22     mov  r1, #0x53000000
23     mov  r2, #0x0
24     str  r2, [r1]
25     mov  pc, lr
26 
27 copy_steppingstone_to_sdram:
28     mov  r1, #0
29     ldr  r2, =SDRAM_BASE
30     mov  r3, #1024*4
31 1:
32     ldr  r4, [r1],#4
33     str  r4, [r2],#4
34     cmp  r1, r3
35     bne  1b
36     mov  pc, lr
37 
38 sdram_init:
39     mov  r1, #MEM_CTL_BASE
40     adrl r2, mem_cfg_val
41     add  r3, r1,#52
42 1:
43     ldr  r4, [r2],#4
44     str  r4, [r1],#4
45     cmp  r1, r3
46     bne  1b
47     mov  pc, lr
48 
49 .align 4
50 mem_cfg_val:
51     
52     .long 0x22011110;
53     .long 0x00000700;
54     .long 0x00000700;
55     .long 0x00000700;
56     .long 0x00000700;
57     .long 0x00000700;
58     .long 0x00000700;
59     .long 0x00018005;
60     .long 0x00018005;    
61     .long 0x008c07a3;
62     .long 0x000000b1;
63     .long 0x00000030;
64     .long 0x00000030;
startup.s

        1.2.1.关看门狗;

    1.2.2.初始化SDRAM;

    1.2.3.复制Norflash前4K内容到SDRAM;

    1.2.4.设置栈;

    1.2.5.跳转到main

  1.3.Makefile

  
1 Main.bin : startup.s main.c
2     arm-linux-gcc -g -c -o startup.o startup.s
3     arm-linux-gcc -g -c -o main.o  main.c
4     arm-linux-ld -Ttext 0x30000000 startup.o main.o -o main_elf
5     arm-linux-objcopy -O binary -S main_elf main.bin
6 
7 clean:
8     rm -f main.bin main_elf *.o
Makefile

 

2.startup.s详解:

  编译链接出来的文件main.bin是烧录到Norflash中0x00000000地址开始的一片内存,但是Makefile中指定的代码段链接地址为0x30000000,代码是如何被执行的?

     位置无关的相对跳转指令概念:    

    1.位置无关的程序跳转。使用相对跳转指令实现程序跳转。指令中所跳转的目标地址用基于当前PC的偏移量来表示,与链接时分配给地址标号的绝对地址值无关,因而代码可以在任何位置进行跳转,实现位置无关性。

    2.位置无关的常量访问。在应用程序中,经常要读写相关寄存器以完成必要的硬件初始化。为增强程序的可读性,利用EQU伪指令对一些常量进行赋值,但在访问过程中,必须实现位置无关性。

    3.使用绝对地址进行跳转,一般是在不同的位置无关代码段之间跳转。

  代码:   

    bl disable_watch_dog                     //链接地址:0x30000000,位置无关型
    bl sdram_init                                 //链接地址:0x30000004,位置无关型
    bl copy_steppingstone_to_sdram    //链接地址:0x30000008,位置无关型
    ldr pc, =on_sdram                         //链接地址:0x3000000b   

           on_sdram:                                    //链接地址:0x30000010
    ldr sp, =0x34000000
    bl main

  所以, 代码是经过一系列动作之后再跳转到0x30000010处的.其中经过关看门狗,初始化SDRAM,复制内容, 然后跳转,最后执行main函数中的点亮LED操作.

 

 

 

  ps:本人学识尚浅,如有错误遗漏之处,敬请指出!

 

  具体参考:

  《嵌入式Linux应用开发完全手册》

  http://blog.chinaunix.net/uid-26694208-id-3989089.html

  http://tscsh.blog.163.com/blog/static/2003201032013439270574