DRAM:基本存储器件是小电容,需要定期充电(刷新),存储速度较慢。
SRAM:不需要刷新,存取速度快,但功耗大,成本高,常用于存储容量不高,但要求存取速度快的场合,比如stepping stone和cache。
内存的内部如同表格,数据就存在每个单元格中。数据读写时,先指定行号(行地址),再指定列号(列地址),这张表称为Logical Bank(L-Bank)。
由于技术、成本等原因,一块内存芯片不可能把所有的单元格都做到一个L-Bank,现在内存内部基本都会分割成4个L-Bank。
内存的寻址需要提供以下几个信息:
内存容量推导计算公式:
内存容量 = L-Bank数目 单元格数目 单元格容量
以下面这款内存芯片为例:
其内存容量为:
64M * 16bit = 128MByte
S3C2440芯片对外提供了27根地址线和32根数据线,单靠芯片上的27根引脚,它只能访问128MB的外设空间。为了扩大外设的访问范围,S3C2440芯片又提供了8个片选信号nGCS0~nGCS7。当某个片选信号nGCSx有效时,则可以通过27根地址线去访问对应这个芯片的128MB空间。所以2440能访问的外设空间总共为8*128=1GB,而1GB(0x40000000)以上的空间,则安排给了2440内部的寄存器,访问这些内部寄存器,则是通过32位的处理器内部总线来完成的。
内存一般放在片选6或片选7上,所以2440的内存起始地址是从0x30000000开始。
单个内存芯片数据位宽是16位,而2440本身的数据线有32根,所以2440使用两个32MB的芯片并联的方式来存储数据。
芯片手册第6章讲解存储控制器的相关寄存器控制,第一个寄存器是BWSCON,用于控制总线宽度和等待状态。
按如下方式配置:
需要设置Bank6和Bank7,因为只有在这两个Bank上才接了内存。
下一组寄存器是BANKCON0~BANKCON5,由于这几个BANK上没有接内存,所以不需要设置,保持默认值即可。
下面要设置的寄存器是BANKCON6和BANKCON7
按如下方式配置:
4.列地址数目,需要从内存芯片上去查找,以column为关键字查找,结果是9bit。
下一个要设置的寄存器是REFRESH,用于控制SDRAM的刷新。
按如下方式设置:
下一个寄存器是BANKSIZE
按如下方式配置:
下一个寄存器是MRSRB6和MRSRB7,用于设置bank6和bank7的模式
需要设置的域只有CL,参考时序图,得到 CAS延时是3个clock(RAS变为低电平到CAS变为低电平的延时),CL=011。
#define mem_contrl 0x48000000 init_sdram: ldr r0, =mem_contrl add r3, r0, #4*13 adrl r1, mem_data @adrl用于将语句标号的地址赋值给寄存器 0: ldr r2, [r1], #4 str r2, [r0], #4 cmp r0, r3 bne 0b @加b表示往前跳转 mov pc, lr mem_data: .long 0x22000000 .long 0x00000700 .long 0x00000700 .long 0x00000700 .long 0x00000700 .long 0x00000700 .long 0x00000700 .long 0x00018001 .long 0x00018001 .long 0x008c04f5 .long 0x000000b1 .long 0x00000030 .long 0x00000030 |
6410拥有32位地址总线,寻址空间为4GB,其中高2GB为保留区域,低2GB又可划分为两部分:主存储区和外设区。
外设区指的是各种寄存器的地址,所有外设寄存器的地址都是从0x70000000开始。
主存储区的内存映像如下图所示:
启动镜像区:用于启动ARM系统,并没有固定的存储介质与之对应,而是通过修改启动选项,把不同的启动介质映射到该区域,比如选择了IROM启动方式后,就把IROM映射到该区域。
内部存储区:包括IROM和ISRAM,IROM实际只有32KB,ISRAM实际只有8KB。
静态存储区:用于访问挂在外部总线上的设备,比如NOR flash、oneNand等。这个区域被分割为6个bank,每个bank128MB,数据宽度最大支持16bit,每个bank由片选Xm0CS0-Xm0CS5选中。
动态存储区:设备的主存储区,安排DDR,两个128MB区域,由片选Xm1CS0-Xm1CS1来进行2个区间的选择。
同样由两片16bit的128MB内存并联而成。
芯片手册第5章是关于存储控制器的介绍,首先查看5.4小节关于内存初始化的流程:
相关顺序描述如下:
5.4.3小节介绍了内存初始化的步骤,如下:
下面参考uboot中关于6410内存初始化的代码进行分析,内存初始化的相关语句从mem_ctrl_asm_init标号开始。
.text .global mem_init mem_init: @set data pin ldr r0, =0x7e00f120 mov r1, #0x0 str r1, [r0] @Enter config state ldr r0, =0x7e001004 mov r1, #0x4 str r1, [r0] @Time parameter, chip configuration, id configuration ldr r0, =0x7e001004 @allow configuration mov r1, #0x4 str r1, [r0] ldr r0, =0x7e001010 @refresh period ldr r1, =( ( 7800 / ( 1000000000/133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e001014 @CAS latency mov r1, #(3 << 1) str r1, [r0] ldr r0, =0x7e001018 @t_DQSS mov r1, #0x1 str r1, [r0] ldr r0, =0x7e00101c @t_MRD mov r1, #0x2 str r1, [r0] ldr r0, =0x7e001020 @t_RAS ldr r1, =( ( 45 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e001024 @t_RC ldr r1, =( ( 68 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e001028 @t_RCD ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e00102c @t_RFC ldr r1, =( ( 80 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e001030 @t_RP ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e001034 @t_RRD ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e001038 @t_WR ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e00103c @t_WTR mov r1, #0x07 str r1, [r0] ldr r0, =0x7e001040 @t_XP mov r1, #0x02 str r1, [r0] ldr r0, =0x7e001044 @t_XSR ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e001048 @t_ESR ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) ) str r1, [r0] ldr r0, =0x7e00100c @内存控制配置寄存器 ldr r1, =0x00010012 @配置控制器 str r1, [r0] ldr r0, =0x7e00104c @32位DRAM配置控制寄存器 ldr r1, =0x0b45 str r1, [r0] ldr r0, =0x7e001200 @片选寄存器 ldr r1, =0x150f8 str r1, [r0] ldr r0, =0x7e001304 @用户配置寄存器 mov r1, #0x0 str r1, [r0] @Excute memory initialization sequence ldr r0, =0x7e001008 @NOP ldr r1, =0xc0000 str r1, [r0] ldr r0, =0x7e001008 @prechargeall ldr r1, =0x0 str r1, [r0] ldr r0, =0x7e001008 @autorefresh ldr r1, =0x4 str r1, [r0] ldr r0, =0x7e001008 @autorefresh ldr r1, =0x4 str r1, [r0] ldr r0, =0x7e001008 @MRS-EMRS muse be set ldr r1, =0xa0000 str r1, [r0] ldr r0, =0x7e001008 @MRS-MRS muse be set ldr r1, =0x80032 str r1, [r0] @Enter Ready state ldr r0, =0x7e001004 mov r1, #0x0 str r1, [r0] @Check until memory state is ready check_ready: ldr r0, =0x7e001000 ldr r1, [r0] mov r2, #0x3 and r1, r1, r2 cmp r1, #0x1 bne check_ready mov pc, lr |
210使用DDR2内存芯片,内存地址空间从0x20000000开始,DRAM0大小是512MB,DRAM1大小是1GB。
210内存芯片数据宽度是8bit,所以210开发板常采用8片或4片128*8bit芯片级联的办法。
参考芯片手册section05_memory, 第1.2.1.3小节关于DDR2内存的初始化。
略