S5PV210的内存分配研究分析
S5PV210内存一般会使用SDRAM和DDR2 (DDR SDRAM),SDRAM的uboot启动网络已经有很多资料的,对于DDR2还有有很多疑惑,如果有错误的地方,请大家一定指出,醍醐灌顶,不胜感激。
1、S5PV210的memory map(物理地址)
如下图:左图是整个芯片的内存空间(物理地址),右图是iROM部分的内存空间(BL0的地址貌似不是物理地址==)

2、U-Boot内存分配图

2.u-boot映像的地址0并非指物理地址0,由不同的启动方式映射到不同的地址。例如v210是映射到0xD0000000处的irom。
3.TEXT_BASE等指向SDRAM的地址均为虚拟地址。
4.TEXT_BASE为顶层Makefile中定义的,例如三星官方BSP中定义的是0xC3E00000,它是程序实际的链接首地址。
5.SDRAM_BASE被MMU映射在0xC0000000。
6._end和__bss_start为链接脚本文件中最后定义的bss段,在链接时确定,并与u-boot映像编译在一起。
7.在bl1段运行时,u-boot映像被复制到TEXT_BASE开始的地址处。
8. u-boot分配用户栈顶的代码为:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ 将0xc3e00000加载到r0
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ r0减去0x4000的malloc域
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ r0减去128字节的全局结构体
#if defined(CONFIG_USE_IRQ)
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) 如果用户有使用IRQ,再减去2*4*1024的中断栈空间
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack */ 为取址终止异常预留3个字空间后设置好用户sp
DMC1 0x4000_0000 ~ 0x7FFF_FFFF 512MB

如果设置chip_base为0x20:
(1)我们挂载的内存为128M,那么这个chip_mask应该设置为0xF8
(2)我们挂载256M内存时,chip_mask应该设置为0xF0
(3)我们挂载512M时,chip_mask应该设置为0xE0
(4)我们挂载1GB内存时,chip_mask就应该设置为0xC0。
以DMC0为例,当DMC0接收到来自AXI的0x2000,0000~0x3fff,ffff内的地址时,会作如下处理:
(1)将AXI地址的高8位与chip_mask相与得到结果,记为X。
(2)将X分别与MEMCONFIG0和MEMCONFIG1的chip_base相比较,如果相等,则打开相应的片选。
假如挂载的内存为128M,且CS0和CS1上分别挂了一片,那么128M=128*1024*1024=0x8000000,则128M内存的偏移范围应该是0x0000,0000~0x07ff,ffff,高位剩余5位,那么,我们把MEMCONFIG0的chip_base设置为0x20,chip_mask设置为0xF8,为了保持内存连续,则需要将MEMCONFIG1的chip_base设置为0x28,chip_mask设置为0xF8,当AXI发来的地址为0x23xx,xxxx时,0x23&0xF8得到0x20,所以,会打开片选CS0,当AXI发来的地址为0x28xx,xxxx时,0x28&0xF8得到0x28,所以,会打开片选CS1,依此类推。
特别的,当载在的内存芯片为8bank(8bank内存芯片一般为14/15行地址,10列地址,即容量一般为512M或者1G)时,由于CS1为bank2引脚,为了保持CS0时钟处于片选状态,对于512M内存来讲需要将chip_mask设置为0xE0,这是因为512M=512*1024*1024=0x2000,0000,也就是说,512M内存的偏移应该为0x0000,0000~0x1fff,ffff,所以高位剩余3位,即0xE0,当然了,如果内存为1G=1024*1024*1024=0x4000,0000,即偏移为0x0000,0000~0x3fff,ffff,高位剩余2为,故设置chip_mask为0xC0。这样,就会计算偏移这两个值了。
4、 配置流程
内存芯片的配置比较复杂,好在芯片手册上给出了常用内存类型的初始化序列,TQ210的内存是DDR2的,可以按照如下顺序进行初始化:
1. To provide stable power for controller and memory device, the controller must assert and hold CKE to a logic low level. Then apply stable clock. Note: XDDR2SEL should be High level to hold CKE to low.
2. Set the PhyControl0.ctrl_start_point and PhyControl0.ctrl_inc bit-fields to correct value according to clock frequency. Set the PhyControl0.ctrl_dll_on bit-field to ‘1’ to turn on the PHY DLL.
3. DQS Cleaning: Set the PhyControl1.ctrl_shiftc and PhyControl1.ctrl_offsetc bit-fields to correct value according to clock frequency and memory tAC parameters.
4. Set the PhyControl0.ctrl_start bit-field to ‘1’.
5. Set the ConControl. At this moment, an auto refresh counter should be off.
6. Set the MemControl. At this moment, all power down modes should be off.
7. Set the MemConfig0 register. If there are two external memo ry chips, set the MemConfig1 register.
8. Set the PrechConfig and PwrdnConfig registers.
9. Set the TimingAref, TimingRow, TimingData and TimingPower registers according to memory AC parameters.
10. If QoS scheme is required, set the QosControl0~15 and QosConfig0~15 registers.
11. Wait for the PhyStatus0.ctrl_locked bit-fields to change to ‘1’. Check whether PHY DLL is locked.
12. PHY DLL compensates the changes of delay amount caused by Process, Voltage and Temperature (PVT) variation during memory operation. Therefore, PHY DLL should not be off for reliable operation. It can be off except runs at low frequency. If off mode is used, set the PhyControl0.ctrl_force bit-field to correct value according to the PhyStatus0.ctrl_lock_value[9:2] bit-field to fix delay amount. Clear the PhyControl0.ctrl_dll_on bit-field to turn off PHY DLL.
13. Confirm whether stable clock is issued minimum 200us after power on
14. Issue a NOP command using the DirectCmd register to assert and to hold CKE to a logic high level
15. Wait for minimum 400ns.
16. Issue a PALL command using the DirectCmd register.
17. Issue an EMRS2 command using the DirectCmd register to program the operating parameters.
18. Issue an EMRS3 command using the DirectCmd register to program the operating parameters.
19. Issue an EMRS command using the DirectCmd register to enable the memory DLLs.
20. Issue a MRS command using the DirectCmd register to reset the memory DLL.
21. Issue a PALL command using the DirectCmd register.
22. Issue two Auto Refresh commands using the DirectCmd register.
23. Issue a MRS command using the DirectCmd register to program the operating parameters without resetting the memory DLL.
24. Wait for minimum 200 clock cycles.
25. Issue an EMRS command using the DirectCmd register to program the operating parameters. If OCD calibration is not used, issue an EMRS command to set OCD Calibration Default. After that, issue an EMRS command to exit OCD Calibration Mode and to program the operating parameters.
26. If there are two external memory chips, perform steps 14~25 for chip1 memory device.
27. Set the ConControl to turn on an auto refresh counter. 28. If power down modes is required, set the MemControl registers.
上面就是手册上给出的DDR2型内存芯片的初始化序列,但是单纯的根据上面的步骤配置可能有些困难,这时,我们可以参考u-boot的内存初始化代码来初始化内存,最后你会发现u-boot的操作顺序跟上面是完全一致的。
5、代码的链接地址和运行地址等注意事项
配置好内存的代码烧写到Nand运行是正常的,但是用USB方式启动时不正常,目前还没有找到原因,如果有朋友解决了或者有其他问题请留言相告,在这里先说声谢谢。
现在找到原因了,原来S5PV210的USB启动过程跟Nand启动方式不一样,S5PV210以USB方式启动时会先将三星提供的一个固件程序下载到0xd0020010处运行,然后,再将用户代码下载0x23e00000处运行,也就是说,固件程序完成了内存的初始化,因为我们的代码位于0x23e00000处。而我们的代码中再次配置内存时会重置内存,下载到内存中的代码也就丢失了,所以程序执行到内存初始化函数就会挂掉。
为了证明上面的假设,我在代码中加上一段程序,该程序将内存的中代码拷贝到iram的16K以后的位置上(直接拷贝到0xd0020000处有问题,我是拷贝到了0xd0024000处,现在还不知道什么原因),然后将代码跳转到IRAM中,如果代码可以正常运行就可以证明内存初始化部分正常,实验结果是肯定的,下面总结下:
S5PV210以USB方式启动时用户代码是下载到内存中的(0x23e00000处),要使代码以USB方式启动时正常运行,应该注意以下两点:
(1)如果是位置相关的代码,连接地址应该链接到0x23e00000,如果是位置无关码,可以随便指定连接地址。
(2)用户代码需要检验自己运行时的位置,如果运行在内存中则需跳过内存初始化,根据需要决定是否需要代码重定位。
参考网址:http://blog.chinaunix.net/uid-122754-id-3144920.html
http://www.cnblogs.com/Efronc/archive/2012/03/01/2375578.html
S5PV210的内存分配研究分析的更多相关文章
- map的内存分配机制分析
该程序演示了map在形成的时候对内存的操作和分配. 因为自己对平衡二叉树的创建细节理解不够,还不太明白程序所显示的日志.等我明白了,再来修改这个文档. /* 功能说明: map的内存分配机制分析. 代 ...
- list的内存分配机制分析
该程序演示了list在内存分配时候的问题.里面的备注信息是我的想法. /* 功能说明: list的内存分配机制分析. 代码说明: list所管理的内存地址可以是不连续的.程序在不断的push_back ...
- vector的内存分配机制分析
该程序初步演示了我对vector在分配内存的时候的理解.可能有误差,随着理解的改变,改代码可以被修改. /* 功能说明: vector的内存分配机制分析. 代码说明: vector所管理的内存地址是连 ...
- java 字符串内存分配的分析与总结
经常在网上各大版块都能看到对于java字符串运行时内存分配的探讨,形如:String a = "123",String b = new String("123" ...
- mimalloc内存分配代码分析
这篇文章中我们会介绍一下mimalloc的实现,其中可能涉及上一篇文章提到的内容,如果不了解的可以先看下这篇mimalloc剖析.首先我们需要了解的是其整体结构,mimalloc的结构如下图所示 ...
- Java 内存分配全面浅析
本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java.这类文章网上有很多,但大多比较零碎.本文从认知过程角度出发,将带给读者一个系统的介绍. 进入正题前首先要知道的是Java程 ...
- Java内存分配全面浅析
本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java.这类文章网上有很多,但大多比较零碎.本文从认知过程角度出发,将带给读者一个系统的介绍. 进入正题前首先要知道的是Java程 ...
- Java内存分配全面浅析(转)
原文引自CSDN: 本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java.这类文章网上有很多,但大多比较零碎.本文从认知过程角度出发,将带给读者一个 ...
- Java 内存分配全面浅析(转)
本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java.这类文章网上有很多,但大多比较零碎.本文从认知过程角度出发,将带给读者一个系统的介绍. 进入正题前首先要知道的是Java程 ...
随机推荐
- 验证:mysql AUTO_INCREMENT 默认值是1
用mongodb时,有些字段需要做自增,而且是用二十进制字母表示(使用a-t对应0-19),做了一个_auto_increment字段用来保存,但是应该从0开始还是从1开始呢? 和mysql保持一致便 ...
- 如何让C#像JavaScript一样编程
JavaScript是一门动态语言,可以动态的给对象添加属性和方法,非常方便.那么有没有一种方式可以让C#也具备动态添加属性和方法的能力,像Javascript一样进行编程? 下面就介绍一个很不错的框 ...
- 20个免费的 AngularJS 资源和开发教程
曾经,jQuery 无疑是最受欢迎的开源的 JavaScript 库,如今它有了很多的竞争对手,像 AngularJS.React.KnockoutJS 等等.在这里,我想重点关注一下 Angular ...
- PourOver – 快速筛选和排序大的数据集合
PourOver 是一个用于对大数据集合进行快速过滤的 JavaScript 库.它可以在60fps下运行,允许您构建数据研究应用和档案,即不必等待一个数据库调用来呈现查询结果. PourOver 基 ...
- 【初探移动前端开发05】jQuery Mobile (整合版)
前言 为了方便大家看的方便,我这里将这几天的东西整合一下发出. 里面的例子请使用手机浏览器查看. 什么是jQuery Mobile? jquery mobile是jquery在移动设备上的版本,他是基 ...
- 【初探移动前端开发03】jQuery Mobile(上)
前言 到目前为止,我打了几天酱油了,这几天落实了工作,并且看了一部电视连续剧(陈道明-手机),我很少看连续剧了,但是手机质量很高啊,各位可以看看. 我们今天先学习一下jquery mobile的基础知 ...
- spring(4)——自动装配
set注入和构造注入有时在做配置时比较麻烦.所以框架为了提高开发效率,提供自动装配功能,简化配置.spring框架式默认不支持自动装配的,要想使用自动装配需要修改spring配置文件中<bean ...
- Autodesk招聘开发咨询顾问(北京或上海),需要内推的扔简历过来啊
Autodesk现招聘两位二次开发技术顾问,为正式编制.享受所有Autodesk优越的福利资源(额外商业保险,公积金全部由公司支付,年度奖金,季度礼物, 节日礼物, 15天年假,不定期的培训...). ...
- Ubuntu Server 14.04升级Ubuntu Server 16.04
Ubuntu Server 14.04升级Ubuntu Server 16.04 :转 http://blog.csdn.net/chszs 1.终端下执行命令 $ sudo apt-get upda ...
- swift 2.2 语法 (中)
前言: 1.此文中的语法会根据Swift的升级变动而更新. 2.如果需要请移步 -> swift2.2 语法(上).swift 2.2语法(下) 函数 和C语言一样,swift也有函数,性质和我 ...
