arm处理器bank与存储器的bank详解
网络问题:我在网上看到S3C2410A将系统的存储空间分成8个bank,每个bank的大小是128M字节。
每个bank都有一个nGCSx对应 nGCSx被叫做片选,片选上可以连接内存
那是不是一个256M的内存链接到上述一个片选上,因为一个片选对应的bank的大小只有128M,就会浪费128M的物理内存???
网络解答:
>>是的,这个芯片功能比较弱,每个片选对应的地址空间是固定的,不能修改。
>>对于SDRAM只能接在cs7和cs6上,单片256MB的内存芯片好像很少见的,
>>对于256MB的内存,首先他们是多片SDRAM芯片,你可以分别使用这2个片选,一个分128MB。
对于这个网络解答,我理解为,就是说一个256MB的内存,可以用两个片选都连在上面,每个片选分128MB内存,以达到不浪费内存的作用。
对64MB的SDARM理解:(此处所说为存储器的bank(L-BANK))
SDRAM内存工作原理
上面产生的误解关于 Bank ,这个bank 不是 和 S3C2440 芯片有关系(RAM 自身有bank , SDRAM 自身也有bank ,就像书 有 好几章节一样)
所以人们在 SDRAM内部分割成多个 L-Bank,目前基本都是 4个(这也是SDRAM规范中的最高L-Bank数量),由此可见,在进行寻址时就要先确定是哪个 L-Bank,然后在这个选定的 L-Bank中选择相应的行与列进行寻址。因此对内存的访问,一次只能是一个 L-Bank工作。如图2-50
Mini2440使用的SDRAM芯片是32M的HY57V561620,这是一个4Banks*4M*16bit的SDRAM,也就是由4个逻辑块(Logical Bank,简称L-Bank)组成,每个L-Bank有4M存储单元,每个单元是16bit。所有它的数据线是16根(DQ[15:0]);地址线有13根(A[12:0]),其中行地址13根(A[12:0]),列地址9根(A[8:0]);还有两根信号线(BA[1:0])用于选择L-Bank。
两个芯片(U6和U7)并接,就可以组成位宽32位的SDRAM,空间为64M,映射到nGCS6(BANK6),访问的地址空间为0x30000000~0x33ffffff。
这个里面有提到,部分地址线是行和列复用的
存储管理器的使用:
初始化存储管理器,把ARM的4K代码拷贝到SDARM上执行。
Makefile文件:
- led_mempory: start.S led.c
- arm-linux-gcc -c start.S -o start.o
- arm-linux-gcc -c led.c -o led_mempory.o
- arm-linux-ld -Ttext=0x30000000 start.o led_mempory.o -o led_mempory
- arm-linux-objcopy -O binary led_mempory led_mempory.bin
- arm-linux-objdump -D -m arm led_mempory > led_mempory.dis
- clean:
- rm -f start.o led_mempory.o led_mempory led_mempory.bin led_mempory.dis *.o
初始化存储管理器、堆栈、关闭看门狗:
- @##########################################################
- @ 初始化存储器管理器,设置堆栈,调用main函数 #
- @##########################################################
- .equ sdarm_abs, 0x30000000 @SDAM其实地址
- .equ mempory, 0x48000000 @存储管理器寄存器的起始地址
- .text
- .global _start
- _start:
- bl WDOG @关闭看门狗
- bl setmempory @初始化存储器管理器
- bl cp_to_dsarm @拷贝前4K代码到SDARM中
- ldr sp, =0x34000000 @初始化堆栈
- ldr pc, =main @到SDARM中执行
- WDOG:
- ldr r0, =0x53000000
- mov r1, #0x0
- str r1, [r0]
- mov pc, lr
- setmempory:
- ldr r0, =mempory
- adrl r2, table
- add r1, r0, #52
- m_loop:
- ldr r4, [r2], #4
- str r4, [r0], #4
- cmp r1, r0
- bne m_loop
- mov pc, lr
- cp_to_dsarm:
- ldr r0, =sdarm_abs
- mov r1, #0x0
- add r2, r1, #4*1024
- loopcopy: @循环拷贝
- ldmia r1!, {r3-r10}
- stmia r0!, {r3-r10}
- cmp r1, r2
- bne loopcopy
- mov pc, lr
- .align 4
- table:
- .long 0x22011110 @ BWSCON
- .long 0x00000700 @ BANKCON0
- .long 0x00000700 @ BANKCON1
- .long 0x00000700 @ BANKCON2
- .long 0x00000700 @ BANKCON3
- .long 0x00000700 @ BANKCON4
- .long 0x00000700 @ BANKCON5
- .long 0x00018005 @ BANKCON6
- .long 0x00018005 @ BANKCON7
- .long 0x008C07A3 @ REFRESH
- .long 0x000000B1 @ BANKSIZE
- .long 0x00000030 @ MRSRB6
- .long 0x00000030 @ MRSRB7
点亮LED:
- #include "led.h"
- void time(unsigned int t)
- {
- while(t--);
- }
- int main()
- {
- GPBCON &= (~(0x3 << 12 | 0x3 << 14 | 0x3 << 16 | 0x3 << 10));
- GPBCON |= (0x1 << 12 | 0x1 << 14 | 0x1 << 16 | 0x1 << 10);
- while(1)
- {
- GPBDAT &= (~(0x1 << 5 | 0x1 << 6 | 0x1 << 7 | 0x1 << 8));
- time(50000);
- GPBDAT |= (0x1 << 5 | 0x1 << 6 | 0x1 << 7 | 0x1 << 8);
- time(50000);
- }
- return 0;
- }
led.h
- #ifndef _LEDD_H_
- #define _LEDD_H_
- #define GPIO 0x56000000 /*GPIO的基地址*/
- #define GPBCON (*(volatile unsigned long *)(GPIO + 0x10))
- #define GPBDAT (*(volatile unsigned long *)(GPIO + 0x14))
- #endif
链接地址是CPU能够看到的地址,也是程序员编写程序用到的虚拟地址,一般要经过MMU的转换映射到实际的物理地址。CPU对内存的访问一般是CPU发送一个它看到的地址,经过MMU的转化,在通过存储管理器,最终访问到实际的物理地址。本实验的链接地址为0x30000000,并且没有初始化MMU,CPU发出的地址实际就直接对应到实际的物理地址,通过存储管理器访问内存。这也是本实验能够成功的原因。