之前已经做过64M到128MRAM的扩展,但是当时是两块64M的合成128M,这在以前的博文里有说明。并且很容易就能搞定,但是这次换了一个单片128M的RAM,居然一直显示是64M,只显示一半的RAM,一直以为是硬件连线的问题,所以好几天都没有去管,但是最后却发现是自己没有深入考虑,自责一下。
平台用的是三星的SMDK2450,想将两片64M的SDRAM换成一片128M的DDR RAM。之前一直调不过,是因为,三星的memory layout都是基于64M的RAM,而我之前所做的扩展,两块64M的RAM是相对独立的,物理地址相连,或者物理地址不相连,但是虚拟映射的地址是相连,这样的话,不会影响到ISR中断向量表,栈基址。但是如果是单片128M的RAM的话,由于没有修改memory layout,这样的话ISR中断向量表就会处于128M的中间位置,这样的话就无法识别出128M的内存,如果仅仅修改config.bib,将RAM的长度扩大,这样的话,虽然可以识别到128M的内存,但是它是不能工作的,系统会挂掉。
所以需要重新设计128M的memory layout。修改config.bin,修改如下,利用环境变量来区分:
IF BSP_DDR128M
RAM 81B00000 05E00000 RAM;扩展64M的RAM
ELSE
RAM 81B00000 01E00000 RAM;这个是原来的状态,编译系统的时候只需要设置环境变量就可以生成想要的系统,也有利于保持原貌。
ENDIF
;这部分也需要修改,需要重新设置显存的地址,不仅这里需要改,代码里与显存相关的也需要改。后面会有说明。
IF BSP_DTR_DDR128M
ARGS 80020000 00000800 RESERVED
SLEEP 80028000 00002000 RESERVED
EDBG 80030000 00020000 RESERVED
DISPLAY 87900000 00600000 RESERVED
CF_DMA_BUF 87FE0000 00020000 RESERVED
ELSE
ARGS 80020000 00000800 RESERVED
SLEEP 80028000 00002000 RESERVED
EDBG 80030000 00020000 RESERVED
DISPLAY 83900000 00600000 RESERVED
CF_DMA_BUF 83FE0000 00020000 RESERVED
ENDIF
这样就完成了对config.bib的修改。
其实128M的RAM,RAS,CAS(行列选通)都会有改变,所以这部分需要先设置,在S3c2450.inc里会有这方面的设置。
如下:
IF :DEF: BSP_DDR128M(这里RAS与CAS只需该bank0就行,bank1不管也行,因为只有一个片选,这里我全改了)
RASBW0 EQU 3 ; RAS addr 00=11bit,01-12bit,10=13bit, 11=14bit
RASBW1 EQU 3 ; RAS addr 00=11bit,01-12bit,10=13bit, 11=14bit
CASBW0 EQU 2 ; CAS addr 00=8bit,01-9bit,10=10bit, 11=11bit
CASBW1 EQU 2 ; CAS addr 00=8bit,01-9bit,10=10bit, 11=11bit
ADDRCFG0 EQU 0 ; addre configure
; 00={BA,RAS,CAS}, 01={RAS,BA,CAS}
ADDRCFG1 EQU 0 ; addre configure
ELSE
RASBW0 EQU 2 ; RAS addr 00=11bit,01-12bit,10=13bit, 11=14bit
RASBW1 EQU 2 ; RAS addr 00=11bit,01-12bit,10=13bit, 11=14bit
CASBW0 EQU 2 ; CAS addr 00=8bit,01-9bit,10=10bit, 11=11bit
CASBW1 EQU 2 ; CAS addr 00=8bit,01-9bit,10=10bit, 11=11bit
ADDRCFG0 EQU 1 ; addre configure
; 00={BA,RAS,CAS}, 01={RAS,BA,CAS}
ADDRCFG1 EQU 1 ; addre configure
ENDIF
在这个文件还需要配置RAM的类型,比如我之前用的是SDRAM,现在变成了DDR RAM,这部分比较简单。
硬件方面的设置配置完成后,就需要对ISR中断向量表的设置。寻找和中断向量表相关的文件
三星的板子的机制就是上电加载stepldr,然后stepldr引导eboot,eboot引导os启动,所以RAM这部分的东西在上电后就需要用到,
在stepldr的目录下有option.h,option.inc这里面就涉及到ISR向量表位置问题。如下:
option.h中的改动。
#ifdef BSP_DDR128M(对应128M RAM的地址空间)
#define _ISR_STARTADDRESS (0x37ffff00)
#define _MMUTT_STARTADDRESS (0x37ff8000)
#define _STACK_BASEADDRESS (0x37ff8000)
#define HEAPEND (0x37ff0000)
#else(对应64M RAM的地址空间)
#define _ISR_STARTADDRESS (0x33ffff00)
#define _MMUTT_STARTADDRESS (0x33ff8000)
#define _STACK_BASEADDRESS (0x33ff8000)
#define HEAPEND (0x33ff0000)
#endif
option.inc文件里的改动
IF :DEF: BSP_DDR128M(这里是汇编里的宏定义,以前的文章有提到。)
_ISR_STARTADDRESS EQU 0x37ffff00
ELSE
_ISR_STARTADDRESS EQU 0x33ffff00
ENDIF
在S3c2450.inc文件里也有这部分的设置:(和上面相似)
IF :DEF: BSP_DDR128M
_ISR_STARTADDRESS EQU 0x37ffff00
ELSE
_ISR_STARTADDRESS EQU 0x33ffff00
ENDIF
处理完这些就要映射128M RAM和在汇编里初始化RAM
在oemaddrtab_cfg.inc文件里对整个128MRAM的地址映射
IF :DEF: BSP_DDR128M(虚拟地址,物理地址,长度)
DCD 0x80000000, 0x30000000, 128 ; 128 MB DRAM BANK 6
ELSE
DCD 0x80000000, 0x30000000, 64 ; 64 MB DRAM BANK 6
ENDIF
下面进行初始化,在stepldr和eboot目录下都有startup.s文件,这里会对RAM初始化。
stepldr目录下的文件修改为:
[BSP_DDR128M_S=1
ldr r9, =0x08000000 ; 128MB of RAM.
]
[BSP_DTR_DDR128M_S=0
ldr r9, =0x04000000 ; 64MB of RAM.
]
这是汇编下的宏定义格式其中BSP_DDR128M_S我在S3c2450.inc里有定义,这部分内容可以参见ARM汇编指令部分。
GBLA BSP_DDR128M_S
IF :DEF: BSP_DDR128M
BSP_DDR128M_S SETA 1 ; 1
ELSE
BSP_DDR128M_S SETA 0 ; 0
ENDIF
eboot中的文件修改:这部分和stepldr里的操作是相似的。下面红字为初始化的代码,将r3赋值为128.
[ BSP_DDR128M_S=1 ;
mov r3, #128
]
[ BSP_DTR_DDR128M_S=0 ;
mov r3, #64
]
45 mov r2, r1 ; (r2) = virtual address to map Bank at
cmp r2, #0x20000000:SHR:BANK_SHIFT
add r2, r10, r2, LSL #BANK_SHIFT-18
strlo r0, [r2]
add r0, r0, #0x00100000 ; (r0) = PTE for next physical page
subs r3, r3, #1
add r1, r1, #1
bgt %b45
以上基本完成了对DDR RAM的配置,但是还有config中显存的设置,由于config中显存地址已经改变,所以代码中也需要改变。
这部分地址是在头文件image_cfg.h中定义的,所以只需要修改这部分就行。
#ifdef BSP_DDR128M
#define IMAGE_FRAMEBUFFER_UA_BASE 0xA7900000
#define IMAGE_FRAMEBUFFER_DMA_BASE 0x37900000
#else
#define IMAGE_FRAMEBUFFER_UA_BASE 0xA3900000
#define IMAGE_FRAMEBUFFER_DMA_BASE 0x33900000
#endif
这里改完之后还要修改platform.reg,因为这里也牵涉到显存地址的问题。
IF BSP_DDR128M
"LCDVirtualFrameBase"=dword:A4100000
"LCDPhysicalFrameBase"=dword:34100000
ELSE
"LCDVirtualFrameBase"=dword:A0100000
"LCDPhysicalFrameBase"=dword:30100000
ENDIF
显存地址部分,其实就是在其基础上增加64M就行。
以上基本就是我修改单片128M DDR RAM的做法。可能比较凌乱,但是大家只要明白内存结构图需要重新分配,
文件基本就解决一半了。
个中可能会出现错误,希望指点,扔砖。