210学习日记(8)
--支持DDR
要支持DDR,仅仅只需要做一些初始化工作就行,而在S5PV210芯片手册中的598页已经给出了相信的初始化话步骤,我就不再多说什么了。
另外大家可以听一下韦东三的6410的一期视频里面关于DDR的视频,会对大家对DDR的了解有所帮助。
另外推荐大家看两篇文章:
1).DDR2_SDRAM操作时序.pdf
2).内存的原理和时序(SDRAM、DDR、DDR-Ⅱ、Rambus_DRAM).pdf
参考代码我已经给出(其实我也是参考u-boot里面的,只是自己从头对照寄存器去理解了一下,完全符合598页的初始化步骤),放在了"Tiny210学习日记_代码"目录下了,名为"7_ddr"
注意:之前的代码,包括该部分代码,都没有重定位的操作,IROM最多可以拷贝16K的代码到IRAM中,够用了!
但是,由于后面我会讲到LCD显示图片,声卡播放WAV文件,bootloader也随之慢慢变大,16K的大小可能不够,再加上现在已经把重定位的条件都准备好了,所以接下来将是重定位。(相关知识,大家可以学习韦东三一期视频的重定位部分),这里,我就不在细说,直接给出代码,和讲几个关键地方。
以下为start.s的代码:
.global _start
_start:
ldr sp, =0xD0030000 /* 初始化栈,因为后面要调用C函数 */
bl clock_init /* 初始化时钟 */
bl ddr_init /* 初始化内存 */
bl nand_init /* 初始化NAND */
ldr r0, =0x36000000 /* 要拷贝到DDR中的位置 */
ldr r1, =0x0 /* 从NAND的0地址开始拷贝 */
ldr r2, =bss_start /* BSS段的开始地址 */
sub r2,r2,r0 /* 要拷贝的大小 */
bl nand_read /* 拷贝数据 */
/* 以下将BSS段清0 */
clean_bss:
ldr r0, =bss_start
ldr r1, =bss_end
mov r3, #0
cmp r0, r1
ldreq pc, =on_ddr
clean_loop:
str r3, [r0], #4
cmp r0, r1
bne clean_loop
ldr pc, =on_ddr
on_ddr:
ldr sp, =0x3f000000 /* 重新初始化栈,指向内存 */
ldr pc, =main
注意:
1).ldr r1, =0x0不能写成adr r1, =_start,因为拷贝数据是从Nand Flash的0地址开始拷贝,而adr r1, =_start表示当前程序执行的地址,该地址是0xD0020000而不是0(我在"Tiny210学习日记(2)"中已讲过)。
2).大家注意位置无关码,以及r0对应C函数的参数1,r1对应C函数的参数2,r2对应C函数的参数3的问题!!
以下为连接脚本:
SECTIONS {
. = 0x36000010; /* 注意这个值 */
.text : {
* (.text)
}
. = ALIGN(4);
.rodata : {
* (.rodata)
}
. = ALIGN(4);
.data : {
* (.data)
}
. = ALIGN(4);
bss_start = .;
.bss : { *(.bss) *(COMMON) }
bss_end = .;
}
注意:
连接地址一定要是0x36000010,而不是0x36000000,虽然我们是将Nand Flash的数据拷贝到0x36000000地址处,但是我在"Tiny210学习日记(2)"中已讲过,前16字节的数据是头部信息,而不是真正的可执行代码!!
重定位的相应代码放在了"Tiny210学习日记_代码"目录下了,名为"8_reload"。
注:
如有问题,请到韦东山LINUX视频讨论群里面,我们一起讨论学习,或者加我QQ:317312379