1.代码重定位实战:
ldr和 adr都是伪指令,区别是ldr是长加载、adr是短加载。
重点:adr指令加载符号地址,加载的是运行时地址;ldr加载符号地址时,加载的是链接地址。
深入分析:通过adr和ldr分别用于加载运行地址和链接地址,就可以判断是否需要重定位。
adr是相对于PC的加减
ldr是从内存里面读取值
重定位就是汇编代码中的copy_loop函数,代码的作用是使用循环结构来逐句复制代码到链接地址。
复制的源地址是SRAM的0xd0020010,复制目标地址是SRAM的0xd0024000,复制长度是bss_start减去_start bss 段(bss段中就是 0初始化的全局变量)不需要重定位。
清理完bss断后重定位就结束了,但是当前的状况是:
ldr pc,led_blink
2.SDRAM引入
DDR: DDR就是DDR SRAM ,是SDRAM的升级版
类似于SDRAM和SRAM,还有NorFlash和Nandflash(硬盘)这两个
正是因为硬件本身特性有限制,所以才导致启动代码比较怪异、比较复杂。而我们研究裸机是为了研究uboot,在uboot中充分利用了各种硬件特性,处理了硬件特性。
SDRAM在系统中属于Soc外接设备,(外部设备,随着半导体技术发展,很多东西都逐渐集成到Soc内部去了。现在还长期在外部的一般有:flash、SDRAM/DDR、网卡芯片如DM9000、音频Codec. 现在有些高集成度的芯片也试图把这几个集成进去,做成真正单芯片解决方案)
SDRAM通过地址总线和数据总线接口(总线接口)与Soc通信。
开发板原理图使用的是K4T1G16QQ,但是实际开发板上贴的不是这个,是另一款。但是这两款是完全兼容的进行软件编程分析的时候完全可以参考K4T2G64QQ的文档。
SDRAM的市场特征就导致市场标准化,大部分时候细节参数(芯片原厂家)都会给你一个参考值
K4T1F164QE:
K表示三星产品
4表示是DRAM
T表示产品号码
1G表示容量(1Gb,128MB,我们的开发板x210上用了4片相同的内存,所以总容量是128x4=512MB,)16表示单芯片是16位宽的,4表示4bank
三星官方的数据手册上其实没有什么芯片相关的参数设置信息,都是芯片选型与外观分装·封装方面的信息,选型是给产品经理来看的,封装和电压信息是给硬件工程师看的。软件工程师最关注的是工作参数信息,但是数据手册没有。
3.SDRAM初始化
S5PV210 共有两个内存端口(就好像有两个内存插槽)。在结合查阅数据手册中内存映射部分,可知:两个内存端口分别是DRAM0和DRAM1:
DRAM0:内存地址范围:0x2000000~0x3FFFFFFF(512MB),对应引脚是Xm1xxxx
DRAM1:内存地址范围:0x40000000~0x7FFFFFFF(1024MB),对应引脚是Xm2xxxx
结论:
原理图中每个DDR端口都3类总线构成:地址总线(14根)+控制总线+数据总线(32根)
原理图中画出4片芯片的一页,可以看出:x210开发板共使用了4片芯片(每片1Gb=128MB,共512MB),每片内存的数据总线都是16位的(单芯片是16位内存)。如何由16位内存得到32位内存呢? 可以使用并联方法。在原理图上横向的2颗内存芯片就是并联连接的。并联时地址总线解法一样,但是数据总线要加起来。这样连接相当于在逻辑上可以把这2颗内存芯片看成是一个(这一个芯片是32位的,接在Xmluan·端口上)。
这个框图是128x8结构的,这里指的是8bank,每bank 128Mbit。
210的DDR端口信号中有BA0~BA2,接在内存芯片上的BA0~BA2上,这些引脚就是用来选择bank的。
每个bank内部有128Mb,通过row address (14位) +columnaddress(10位)的方式来综合寻址。
一共能寻址的范围是:2的14次方*2的10次方 = 2的24次方。 对应16MB(128Mbit)内存。
3.汇编初始化SDRAM
SDRAM初始化使用一个函数sdram_asm_init,函数在sdram_init.s文件中实现,是一个汇编函数。
强调:汇编实现的函数在返回时明确使用返回指令(mov pc, lr)
首先,DDR初始化和Soc中的DDR控制器有关,也和开发板使用的DDR芯片有关,和设计时DDR的连接方式也有关。
S5PV210的DDR初始化步骤在Soc数据手册,由
可知 初始化DDR共需 27个步骤。
因为DDR芯片和S5PV210之间是通过很多总线连接的,总线的物理表现就是很多个引脚,也就是说DDT芯片和S5PV210芯片
SDRAM 未完成学习
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
4.时钟系统简介
在S5PV210属于第三种,为什么这么设计?
1,为什么比用外部高频晶振产生高频信号直接给CPU?
芯片外部电路不适宜使用高频率,因为传导辐射比较难控制;高频率的晶振太贵了。
2,为什么要内部先高频然后在分频?
主要因为SoC内部有很多部件都需要时钟,而且各自需要的时钟频率不同,没法统一供应。因此设计思路是PLL后先得到一个最高的频率(1GHZ、1.2GHZ),然后格外设都有自己的分频器再来分频得到自己想要的频率。
5.S5PV210的时钟系统简介
APLL:Cortex-A8 MSYS域
MPLL:DSYS & PSYS
VPLL: Video视频相关模块
6.S5PV210时钟域详解
ARMCLK:给CPU内核工作的时钟,就是所谓的主频。
HCLK_MSYS: MSYS域高频时钟,给DMC0和DMC1使用
PCLK_MSYS: MSYS域的低频时钟
HCLK_IMEM:给iROM和iRAM(合称iMEM)使用
HCLK_DSYS:~高频时钟
PCLK_DSYS:~低频时钟
HCLK_PSYS:~高频时钟
PCLM_PSYS~低频时钟
总结:210内部的各个外设都是接在(内部AMBA总线)总线上面的,AMBA总线有1条高频分支叫AHB,有一条低频分支APB。上面的各个域都有各自对应的HCLK_XXX和PCLK_XXX,其中HCLK_XXX就是这个域中AHB总线的工作频率;PCLK_XXX就是XXX这个域APB总线的工作频率。
SoC内部的各个外设其实是挂在总线上工作的,也就是说这个外设的时钟来自于他挂在的总线,譬如串口UART挂在PSYS域下的APB总线上,因此串口的时钟来源是PCLK_PSYS。
我们可以通过记住和分析上面的这些时钟域和总线数值,来确定我们各个外设的具体时钟频率。
各时钟典型值(默认值,iROM中设置的值)
(1)当210刚上电时,默认是外部晶振+内部时钟发生器产生的24MHz频率的时钟直接给ARMCLK的,这时系统的主频就是24MHz,运行非常慢。
(2)iROM代码执行时第6步中初始化了时钟系统,这时给了系统一个默认推荐运行频率。这个时钟频率是三星推荐的210工作性能和稳定性最佳的频率。
(3)各时钟的典型值:
freq(ARMCLK) =1000 MHz
freq(HCLK_MSYS) =200 MHz
freq(HCLK_IMEM) =100 MHz
freq(PCLK_MSYS) =100 MHz
freq(HCLK_DSYS) =166 MHz
freq(PCLK_DSYS) =83 MHz
freq(HCLK_PSYS) =133 MHz
freq(PCLK_PSYS) =66 MHz
freq(SCLK_ONENAND) = 133 MHz, 166 MHz
6.210时钟体系框图详解
1. xPLL_LOCK
xPLL_LOCK寄存器主要控制PLL锁定周期的。
2.xPLL_CON/xPLL_CON0/xPLL_CON1
PLL_CON寄存器主要用来打开/关闭PLL电路,设置PLL的倍频参数,查看PLL锁定状态等
3.CLK_SRCn(n:0~6)
CLK_SRC寄存器是用来设置时钟来源的,对应时钟框图中的MUX开关。
4.CLK_SRC_MASKn
CLK_SRC_MASK决定MUX开关n选1后是否能继续通过。默认的时钟都是打开的,好处是不会因为某个模块的时钟关闭而导致莫名其妙的问题,坏处是功耗控制不精细、功耗高。
5.CLK_DIVn
各模块的分频器参数配置
6.CLK_GATE_x
类似于CLK_SRC_MASK,对时钟进行开关控制
7.CLK_DIV_STATn
8.CLK_MUX_STATn
这两类状态位寄存器,用来查看DIV和MUX的状态是否已经完成还是在进行中
总结:其中最重要的寄存器有3类:CON、SRC、DIV。其中CON决定PLL倍频到多少,SRC决定走哪一路,DIV决定分频多少。
7.汇编实现时钟设置代码详解
第一步:先选择不使用PLL。让外部2424MHz原始时钟直接过去,绕过APLL那条路
第二步:设置锁定时间。默认值为0x0FFF,保险起见我们设置为0xFFFF
第三步:设置分频系统,决定由PLL出来的最高时钟如何分频得到各个分时钟。
第四步:设置PLL,主要是设置PLL的倍频系数,决定由输入端24MHz的原始频率可以得到多大的输出频率。我们默认设置输出ARMCLK为1GHz
第五步:打开PLL。 前面4步已经设置好了所有的开关和分频系数,本步骤打开PLL后,PLL开始工作,锁定频率后输出,然后经过分频得到各个频率。
总结:以上五步,其实真正涉及到的寄存器只有5个而已。
CLK_SRC寄存器其实是用来设置MUX开关的。在这里现将该寄存器设置为全0,主要是bit0和bit4设置0,表示APLL和MPLL暂时都不启用。
设置PLL锁定延时的。官方推荐值为0xFFF,我们设置为0xFFFF。
1.6.6.4、CLK_DIV寄存器的设置分析
0x14131440这个值的含义分析:
PCLK_PSYS = HCLK_PSYS / 2
HCLK_PSYS = MOUT_PSYS / 5
PCLK_DSYS = HCLK_DSYS / 2
HCLK_DSYS = MOUT_DSYS / 4
·······
HCLK_MSYS = ARMCLK / 5
ARMCLK = MOUT_MSYS / 1
1.6.7.汇编实现时钟设置代码详解2
1.6.7.1、PLL倍频的相关计算
(1)、我们设置了APLL和MPLL两个,其他两个没有管。
(2)、APLL和MPLL设置的关键都是M、P、S三个值,这三个值都来自于官方数据手册的推荐值
(3)、M、P、S的设置依赖《4.2.C语言位运算》中讲过的位运算技术。
1.6.7.2、结合寄存器、时钟框图、代码三者综合分析S5PV210的时钟系统
分析时记得在图上做标记(把MUX开关选哪个和DIV分频多少都标出来)然后清楚了。