首页 > 代码库 > 跟着韦老师学Linux学习笔记(二)-存储管理器

跟着韦老师学Linux学习笔记(二)-存储管理器

(1)、CPU操作外设的基本原理图

技术分享

由图可知,CPU要想访问一个外设,是要通过存储管理器来实现的。本篇中,主要是通过操作SDRAM来实现存储管理器的学习。

(2)、配置原理和步骤

访问一个芯片需要的配置信息:

1、  片选信号

2、  地址线

3、  数据线,即使数据宽度

4、  时钟\频率

5、  芯片相关的东西:对SDRAM来说

a)         行地址有多少位

b)         列地址有多少位

c)         BANK有多少位

技术分享

 

操作一个SDRAM的步骤就是:

a、  首先通过片选信号选中SDRAM

b、  然后确定在哪一个BNAK里面存储

c、  然后发出行地址,在发出列地址,确定在SDRAM的数据位置

 

(3)、硬件相关信息

技术分享

                            SDRAM原理图

技术分享

                            SDRAM芯片手册

技术分享

                            2440的存储控制器手册

 

通过查看原理图和数据手册可知SDRAM的配置数据如下:

a、  数据位宽32位,因为用到了2片SDRAM,一片是16位。

b、  行13位、列9位,由图SDRAM芯片手册可知。

c、  刷新周期 64ms/8192

d、  BANK有4位,由图2440的存储控制器手册可知,BANK地址是A[25:24],。

查看2440手册可知,SDRAM的硬件连接分配如下图

技术分享

SDRAM的地址是从ADDR2~ADDR14,而没有ADDR0和ADDR1,因为我们的内存访问是以32位访问的,每次读写都是4个字节,这就导致了地址ADDR0和ADDR1代表的地址0、1、2和3是无法被单个读取的,每次都是把地址0、1、2和3的数据以一个32位的数据读出,所以忽略地址线ADDR0和ADDR1,地址线为ADDR2~ADDR14。

2440有8个bank,可以接8个类似SDRAM的外设。而我们的SDRAM接在了BANK6上面,起始地址是0x30000000,我们的SDRAM是64MB,所以访问空间是0x30000000~0x33FFFFFF。

(4)、程序代码

 1 .equ        MEM_CTL_BASE,   0x48000000  @因为存储控制器的起始地址是0x48000000
 2 .equ        SDRAM_BASE,   0x30000000    @如上SDRAM的起始访问地址是0x30000000
 3 .text
 4 .global _start
 5 _start:
 6     bl  disable_watch_dog               @ 关闭WATCHDOG,否则CPU会不断重启
 7     bl  memsetup                      @ 设置存储控制器
 8     bl  copy_steppingstone_to_sdram     @ 复制代码到SDRAM中
 9     ldr pc, =on_sdram                   @ 跳到SDRAM中继续执行
10 on_sdram:
11     ldr sp, =0x34000000                 @ 设置堆栈,因为程序被拷贝到SDRAM里面运行,栈空间设置为SDRAM的前4k内容。
12     bl  main
13 halt_loop:
14     b   halt_loop
15 
16 disable_watch_dog:
17     @ 往WATCHDOG寄存器写0即可
18     mov r1,     #0x53000000
19     mov r2,     #0x0
20     str r2,     [r1]
21     mov pc,     lr      @ 返回
22 
23 copy_steppingstone_to_sdram:
24     @ 将Steppingstone的4K数据全部复制到SDRAM中去
25     @ Steppingstone起始地址为0x00000000,SDRAM中起始地址为0x30000000
26     
27     mov r1, #0
28     ldr r2, =SDRAM_BASE  
29     mov r3, #4*1024
30 1:  
31     ldr r4, [r1],#4     @ 从Steppingstone读取4字节的数据,并让源地址加4
32     str r4, [r2],#4     @ 将此4字节的数据复制到SDRAM中,并让目地地址加4
33     cmp r1, r3          @ 判断是否完成:源地址等于Steppingstone的未地址?
34     bne 1b              @ 若没有复制完,继续
35     mov pc,     lr      @ 返回
36 
37 memsetup:
38     @ 设置存储控制器以便使用SDRAM等外设
39 
40     mov r1,     #MEM_CTL_BASE       @ 存储控制器的13个寄存器的开始地址
41     adrl    r2, mem_cfg_val         @ 这13个值的起始存储地址
42     add r3,     r1, #52             @ 13*4 = 54
43 1:  
44     ldr r4,     [r2], #4            @ 读取设置值,并让r2加4
45     str r4,     [r1], #4            @ 将此值写入寄存器,并让r1加4
46     cmp r1,     r3                  @ 判断是否设置完所有13个寄存器
47     bne 1b                          @ 若没有写成,继续
48     mov pc,     lr                  @ 返回
49 
50 
51 .align 4
52 mem_cfg_val:
53     @ 存储控制器13个寄存器的设置值
54     .long   0x22011110      @ BWSCON
55     .long   0x00000700      @ BANKCON0
56     .long   0x00000700      @ BANKCON1
57     .long   0x00000700      @ BANKCON2
58     .long   0x00000700      @ BANKCON3  
59     .long   0x00000700      @ BANKCON4
60     .long   0x00000700      @ BANKCON5
61     .long   0x00018005      @ BANKCON6
62     .long   0x00018005      @ BANKCON7
63     .long   0x008C07A3      @ REFRESH
64     .long   0x000000B1      @ BANKSIZE
65     .long   0x00000030      @ MRSRB6
66     .long   0x00000030      @ MRSRB7

程序和之前主要的区别是加入了复制代码到SDRAM的程序。

因为程序最终是在SDRAM里面执行,所以在Makefile里面我们把代码起始段地址设置为了0x30000000.

1 arm-linux-ld -Ttext 0x30000000 head.o leds.o -o sdram_elf

程序具体的执行流程如下:

技术分享

首先程序从NANDFlash启动,并把前4K的内容拷贝包片内RAM中去,然后程序执行,首先关闭看门狗,设置SDRAM相关寄存器,初始化SDRAM。技术分享技术分享

SDRAM初始化完成以后,开始执行copy_steppingstone_to_sdram程序,这个程序是把我们的程序拷贝到SDRAM里面去执行,拷贝完成后程序的起始地址变成0x3000000。并设置4k的栈空间。

 

 

 

 

 

跟着韦老师学Linux学习笔记(二)-存储管理器