分类: LINUX
2012-02-15 21:50:44
在移植bootloader到新嵌入式开发板的过程中经常会碰到初始化DDRx和DDR控制器的问题。而现在较高端的嵌入式CPU中早已集成了DDR2甚至DDR3控制器,这相较于早期使用SDRAM的CPU,在初始化的时候可能会复杂许多。再加上这些代码一般是在系统刚启动的时候运行的,通常为汇编代码,看着那一大坨汇编程序,不免有些恐惧感。但是如果对DDRx内存原理及其与DDRx控制器的关系有些了解的话,这个配置工作其实还是有章可循的。下面我根据自己的开发经验总结如下,但是此处不涉及具体代码,只对一般流程做描述,因为代码必须是和硬件配套的。如果你先看具体代码,请参考uboot中的代码。
一、学习相关的基础知识:
(1)了解DDRx的外部引脚及其作用
(2)了解的大致时序和相关时序参数的关系
(3)了解DDRx的初始化过程以及配置寄存器的功能
对于以上的一些知识,我已经在《关于学习DDR2时值得一看的资料》中总结过了,大家可以去看看。
(4)了解CPU核、内存控制器及DDRx间的关系
过去在PC中他们三者的关系一般是:
而现在的大多数PC构架中,为了性能,CPU多集成了DDRx控制器,所有现在的关系如下:
但是在嵌入式CPU中,他们三者的关系是:
所以在嵌入式系统中初始化DDRx的顺序应该是先初始化好DDRx控制器,然后通过DDRx控制器初始化外部DDRx芯片。
~~~~~~~~~~以下是CPU初始化DDRx代码的一般步骤~~~~~~~~~~~~~
二、配置内存控制器
(1)根据DDRx芯片大小、位宽和连接方式配置控制寄存器(其中包含了地址映射的配置)
(2)根据所用DDRx芯片的AC特性配置控制器的时序参数寄存器
(3)根据电路板和走线的特性配置DDRx控制器中PHY的控制寄存器(当前仅在部分高端嵌入式芯片中需要)
四、初始化外部DDRx芯片
在上面的参数的配置完成后,就可以开始对外部的DDRx芯片执行初始化过程了。这个根据不同的DDRx控制器可能有不同的情况:
(1)手工:需要操作DDRx控制器的寄存器(指令寄存器),按照DDRx的初始化规范来一步一步手工初始化。(例如三星的S5PV210)
(2)自动:只需要在DDRx控制器的寄存器中触发某个位,DDRx控制器就会帮你自动完成初始化。(例如Ti的DM816x)
这两者各有利弊:手动的方式虽然繁琐,但是给程序员更多的控制权和知情权,比如在DDR2的OCD调整中就可以手动实现,优化传输特性。反之自动方式遂简洁,但是(除非你用高级的逻辑分析仪看)你不知道控制器初始化的细节,也无法从中调整,但是就算是这样也必须遵守JEDEC(电子设备工程联合委员会)的DDR2标准文档。
但是从DDR2 的标准来看,初始化中可以设置的变量基本都已经在初始化控制寄存器时给出了,是板级相关不可变的。只有极少数配置和OCD调整是可变的。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
在完成以上工作后,一般DDRx内存就可以通过映射好的地址访问了,此后bootloader一般就会进入代码自拷贝到内存运行的工作。