arm处理器bank与存储器的bank详解

来源:互联网 发布:sql server 排序规则 编辑:程序博客网 时间:2024/05/16 19:43
以s3c2440为例:
处理器的bank(也是R-BANK)说明:
S3C2440是32位的处理器理论寻址范围为2^32即4G,S3C2440使用[26:0]作为地址线,寻址范围128M(下面的图示讲解为什么[26:0]能寻址128M而不是32M),使用[29:27]作为bank选择信号,所以S3C2440可以连接8个外设,如果全部连接存储器就可以达到1GB的内存。在S3C2440中内存为64MB,它使用了第6和第7个bank连接两片32MB的SDAM。由于外设多种多样其位宽也不尽相同,所以每个bank的数据宽度是可以软件编程控制的。

为什么下载程时要下载到0x30000000地址单元执行,或下载文件到0x30000000地址单元再通过写操作写到NAND FLASH?

因为两片SDARM在bank6和bank7上面连接,通过[29:27]的信号决定选择那块bank,所以bank6的起始地址为0x30000000。

对应关系如下表:
处理器bank与存储器的bank - xxhalbert - xxhalbert的博客
注:bank7的起始地址由bank6的结束地址所决定。

网络问题:我在网上看到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

SDRAM 内部结构原理

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处理器bank与存储器的bank - xxhalbert - xxhalbert的博客

arm处理器bank与存储器的bank - xxhalbert - xxhalbert的博客

arm处理器bank与存储器的bank详解 - xxhalbert - xxhalbert的博客

 

arm处理器bank与存储器的bank - xxhalbert - xxhalbert的博客


存储管理器的使用:

初始化存储管理器,把ARM的4K代码拷贝到SDARM上执行。

Makefile文件:

[plain] view plain copy
 print?
  1. led_mempory: start.S led.c  
  2.     arm-linux-gcc -c start.S -o start.o  
  3.     arm-linux-gcc -c led.c   -o led_mempory.o  
  4.     arm-linux-ld  -Ttext=0x30000000 start.o  led_mempory.o -o led_mempory  
  5.     arm-linux-objcopy -O binary led_mempory led_mempory.bin  
  6.     arm-linux-objdump -D -m arm led_mempory > led_mempory.dis  
  7. clean:  
  8.     rm -f start.o led_mempory.o led_mempory led_mempory.bin led_mempory.dis *.o  


初始化存储管理器、堆栈、关闭看门狗:

[plain] view plain copy
 print?
  1. @##########################################################  
  2. @         初始化存储器管理器,设置堆栈,调用main函数            #  
  3. @##########################################################  
  4.   
  5. .equ   sdarm_abs,  0x30000000  @SDAM其实地址  
  6. .equ   mempory,    0x48000000  @存储管理器寄存器的起始地址  
  7.   
  8. .text  
  9. .global _start  
  10. _start:  
  11.   
  12.          bl    WDOG               @关闭看门狗         
  13.          bl    setmempory         @初始化存储器管理器  
  14.          bl    cp_to_dsarm        @拷贝前4K代码到SDARM中  
  15.          ldr   sp,   =0x34000000  @初始化堆栈  
  16.          ldr   pc,  =main         @到SDARM中执行  
  17. WDOG:                             
  18.          ldr  r0,    =0x53000000    
  19.          mov  r1,    #0x0  
  20.          str  r1,    [r0]  
  21.          mov  pc,    lr  
  22.   
  23. setmempory:                  
  24.          ldr  r0,    =mempory  
  25.          adrl r2,    table  
  26.          add  r1,    r0,       #52  
  27. m_loop:                              
  28.          ldr  r4,    [r2],     #4  
  29.          str  r4,    [r0],     #4  
  30.          cmp  r1,    r0  
  31.          bne  m_loop  
  32.          mov  pc,    lr  
  33.   
  34.   
  35. cp_to_dsarm:  
  36.          ldr  r0,    =sdarm_abs  
  37.          mov  r1,    #0x0  
  38.          add  r2,    r1,      #4*1024  
  39. loopcopy:                           @循环拷贝  
  40.          ldmia r1!,   {r3-r10}  
  41.          stmia r0!,   {r3-r10}  
  42.          cmp   r1,    r2  
  43.          bne   loopcopy  
  44.          mov   pc,    lr  
  45.            
  46.   
  47. .align 4  
  48. table:  
  49.     .long   0x22011110      @ BWSCON  
  50.     .long   0x00000700      @ BANKCON0  
  51.     .long   0x00000700      @ BANKCON1  
  52.     .long   0x00000700      @ BANKCON2  
  53.     .long   0x00000700      @ BANKCON3    
  54.     .long   0x00000700      @ BANKCON4  
  55.     .long   0x00000700      @ BANKCON5  
  56.     .long   0x00018005      @ BANKCON6  
  57.     .long   0x00018005      @ BANKCON7  
  58.     .long   0x008C07A3      @ REFRESH  
  59.     .long   0x000000B1      @ BANKSIZE  
  60.     .long   0x00000030      @ MRSRB6  
  61.     .long   0x00000030      @ MRSRB7  
  62.   
  63.            


点亮LED:

[cpp] view plain copy
 print?
  1. #include "led.h"  
  2.   
  3. void time(unsigned int t)  
  4. {  
  5.    while(t--);  
  6. }  
  7.   
  8. int main()  
  9. {    
  10.    GPBCON &=  (~(0x3 << 12 | 0x3 << 14 | 0x3 << 16 | 0x3 << 10));  
  11.    GPBCON |=    (0x1 << 12 | 0x1 << 14 | 0x1 << 16 | 0x1 << 10);  
  12.   
  13.    while(1)  
  14.    {  
  15.       GPBDAT &=  (~(0x1 << 5  | 0x1 << 6  | 0x1 << 7  | 0x1 << 8));  
  16.       time(50000);  
  17.       GPBDAT |=   (0x1 << 5  | 0x1 << 6  | 0x1 << 7  | 0x1 << 8);  
  18.       time(50000);  
  19.    }  
  20.    return 0;  
  21. }  


led.h

[cpp] view plain copy
 print?
  1. #ifndef _LEDD_H_  
  2. #define _LEDD_H_  
  3.   
  4. #define GPIO  0x56000000 /*GPIO的基地址*/  
  5. #define GPBCON (*(volatile unsigned long *)(GPIO + 0x10))   
  6. #define GPBDAT (*(volatile unsigned long *)(GPIO + 0x14))  
  7.   
  8. #endif  


链接地址是CPU能够看到的地址,也是程序员编写程序用到的虚拟地址,一般要经过MMU的转换映射到实际的物理地址。CPU对内存的访问一般是CPU发送一个它看到的地址,经过MMU的转化,在通过存储管理器,最终访问到实际的物理地址。本实验的链接地址为0x30000000,并且没有初始化MMU,CPU发出的地址实际就直接对应到实际的物理地址,通过存储管理器访问内存。这也是本实验能够成功的原因。