u-boot分析(七)----内存初始化
u-boot分析(七)
上篇博文我们按照210的启动流程,分析到了时钟初始化,今天我们继续按照u-boot的启动流程对内存的初始化进行分析。
今天我们会用到的文档:
1. 2440芯片手册:http://download.csdn.net/detail/wrjvszq/8358949
2. 6410芯片手册:http://download.csdn.net/detail/wrjvszq/8358965
3. 210芯片手册:S5PV210_UM_REV1.1(我的不知道为什么传不上去大家去百度搜吧)
4. 内存芯片手册:大家根据自己的内存芯片去找相应的芯片手册
内存的初始化也是比较复杂我们今天会通过以下几点,对内存的初始化进行介绍:
1. 内存基本分类
2. 深入认识内存
3. 编程分析
l 内存基本分类
为了让大家对内存有个初步的认识,简单介绍其分类
1. DRAM
有小电容组成,需要刷新(充电),所以导致速度较慢
1) SDRAM(2440常用)
2) DDR(6410常用)
3) DDR2(210常用)
4) 其他衍生产品
以上几种都是速度依次增高。
2. SRAM
不用刷新,速度快,价格昂贵,比如我们前面提到的垫脚石就是采用的是SRAM
l 深入认识DRAM
1. 表结构:
内存的内部结构如同一张表格,我们称为l-bank类似与下图,其中每个单元格中可以存放数据

2. 内存寻址
内存经过以下信息进行寻址
1) L-Bank
一方面由于技术、成本等原因,不可能只做一个全容量的L-Bank,而另一方面由于SDRAM的工作原理限制,单一的L-Bank将会造成非常严重的寻址冲突,大幅降低内存效率。所以人们在SDRAM内部分割成多个L-Bank。
因此我们在寻址时就要先确定是哪个L-Bank,然后再在这个选定的L-Bank中选择行列地址进行寻址。
2) 行地址(Row)
3) 列地址(Column)
上面已经说明了内存的寻址方法,其实其内部构造如下图

3. 内存芯片容量的计算
内存芯片的容量就是所有的L-Bank中的存储单元的总容量,那么我们可以得到总的存储单元数量
存储单元数量=行数×列数(一个L-Bank的存储单元数量)×L-Bank的数量
那么如何知道一个存储单元的容量呢?其实在内存芯片的文档中都会有说明,大家可以自己找找看。大家也可以参考其芯片命名进行计算,这里有篇博文简单分析了常见内存芯片的命名规则http://blog.chinaunix.net/uid-20964486-id-1831487.html
经过上述内容我们对内存有了一定的了解,接下来我们分析其编程方法。
l 编程分析
我们的芯片通过存储控制器对内存进行访问,我们对内存的初始化起始就是对控制器的初始化,所以我们知道怎么对存储控制器进行初始化,下面以210为例进行分析
1. 初始化流程
通过阅读210的芯片手册(2440、6410也有类似的东西),很轻松我们在可以找到其给出的初始化配置过程




2. 内存的位置
本以为拿到了内存的初始化流程,就可以开始写代码了,但是在写的过程中会发现其有部分硬件的东西需要了解一下,首先是内存的位置,再以前的博文中说过地址布局的问题,下面以210为例进行分析:

从上图可知210的DRAM分为两个区域,DRAM0和DRAM1总共为1.5G大小,分别通过DMC0和DMC1进行控制,我们要根据自己手头的板子进行确定。
3. 代码分析
有了上面的DDR2的初始化流程和地址布局的分析,我们就不难理解210内存的初始化代码,由于u-boot代码太多看着不太清楚,我将自己按照流程写的代码给大家分享一下
#define DMC_PHYCONTROL0 0xf0000018
#define DMC_PHYCONTROL1 0xf000001c
#define DMC_CONCONTROL 0xf0000000
#define DMC_MEMCONTROL 0xf0000004
#define DMC_MEMCONFIG0 0xf0000008
#define DMC_MEMCONFIG1 0xf000000c
#define DMC_PRECHCONFIG 0xf0000014
#define DMC_TIMINGAREF 0xf0000030
#define DMC_TIMINGROW 0xf0000034
#define DMC_TIMINGDATA 0xf0000038
#define DMC_TIMINGPOWER 0xf000003c
#define DMC_PHYSTATUS 0xf0000040
#define DMC_DIRECTCMD 0xf0000010
#define DMC_PWRDNCONFIG 0xf0000028 #define DMC0_MEMCONTROL 0x00202400
#define DMC0_MEMCONFIG_0 0x20F00313
#define DMC0_MEMCONFIG_1 0x00F00313 #define DMC0_TIMINGA_REF 0x00000618
#define DMC0_TIMING_ROW 0x2B34438A
#define DMC0_TIMING_DATA 0x24240000
#define DMC0_TIMING_PWR 0x0BDC0343 .globl init_mem
init_mem:
@ step 2.1
ldr r0, =DMC_PHYCONTROL0
ldr r1, =0x00101000
str r1, [r0] ldr r0, =DMC_PHYCONTROL1
ldr r1, =0x00000086
str r1, [r0] @ step 2.2
ldr r0, =DMC_PHYCONTROL0
ldr r1, =0x00101002
str r1, [r0] @ step
ldr r0, =DMC_PHYCONTROL0
ldr r1, =0x00101003
str r1, [r0] @ step
ldr r0, =DMC_CONCONTROL
ldr r1, =0x0FFF1350
str r1, [r0] @ step
ldr r0, =DMC_MEMCONTROL
ldr r1, =DMC0_MEMCONTROL
str r1, [r0] @ step
ldr r0, =DMC_MEMCONFIG0
ldr r1, =DMC0_MEMCONFIG_0
str r1, [r0] @ step
ldr r0, =DMC_PRECHCONFIG
ldr r1, =0xFF000000
str r1, [r0] @ step 9.1
ldr r0, =DMC_TIMINGAREF
ldr r1, =DMC0_TIMINGA_REF
str r1, [r0] @ step 9.2
ldr r0, =DMC_TIMINGROW
ldr r1, =DMC0_TIMING_ROW
str r1, [r0] @ step 9.3
ldr r0, =DMC_TIMINGDATA
ldr r1, =DMC0_TIMING_DATA
str r1, [r0] @ step 9.4
ldr r0, =DMC_TIMINGPOWER
ldr r1, =DMC0_TIMING_PWR
str r1, [r0] @ step
wait_lock:
ldr r0, =DMC_PHYSTATUS
ldr r1, [r0]
and r2, r1, #0x4
cmp r2, #0x4
bne wait_lock @ step
ldr r0, =DMC_DIRECTCMD
ldr r1, =0x07000000
str r1, [r0] @ step
ldr r1, =0x01000000
str r1, [r0] @ step
ldr r1, =0x00020000
str r1, [r0] @ step
ldr r1, =0x00030000
str r1, [r0] @ step
ldr r1, =0x00010400
str r1, [r0] @ step
ldr r1, =0x00000542
str r1, [r0] @ step
ldr r1, =0x01000000
str r1, [r0] @ step 22.1
ldr r1, =0x05000000
str r1, [r0] @ step 22.2
ldr r1, =0x05000000
str r1, [r0] @ step
ldr r1, =0x00000442
str r1, [r0] @ step 25.1
ldr r1, =0x00010780
str r1, [r0] @ step 25.2
ldr r1, =0x00010400
str r1, [r0] @ step , repeat step14~step25
ldr r1, =0x07100000
str r1, [r0] ldr r1, =0x01100000
str r1, [r0] ldr r1, =0x00120000
str r1, [r0] ldr r1, =0x00130000
str r1, [r0] ldr r1, =0x00110400
str r1, [r0] ldr r1, =0x00100542
str r1, [r0] ldr r1, =0x01100000
str r1, [r0] ldr r1, =0x05100000
str r1, [r0] ldr r1, =0x05100000
str r1, [r0] ldr r1, =0x00100442
str r1, [r0] ldr r1, =0x00110780
str r1, [r0] ldr r1, =0x00110400
str r1, [r0] @ step
ldr r0, =DMC_CONCONTROL
ldr r1, =0x0FF02030
str r1, [r0] ldr r0, =DMC_PWRDNCONFIG
ldr r1, =0xFFFF00FF
str r1, [r0] ldr r0, =DMC_CONCONTROL
ldr r1, =0x00202400
str r1, [r0] mov pc, lr
u-boot分析(七)----内存初始化的更多相关文章
- 【嵌入式开发】裸机引导操作系统和ARM 内存操作 ( DRAM SRAM 类型 简介 | Logical Bank | 内存地址空间介绍 | 内存芯片连接方式 | 内存初始化 | 汇编代码示例 )
[嵌入式开发]ARM 内存操作 ( DRAM SRAM 类型 简介 | Logical Bank | 内存地址空间介绍 | 内存芯片连接方式 | 内存初始化 | 汇编代码示例 ) 一. 内存 ...
- JAVA 从GC日志分析堆内存 第七节
JAVA 从GC日志分析堆内存 第七节 在上一章中,我们只设置了整个堆的内存大小.但是我们知道,堆又分为了新生代,年老代.他们之间的内存怎么分配呢?新生代又分为Eden和Survivor,他们的比 ...
- Spring Boot 2 (七):Spring Boot 如何解决项目启动时初始化资源
Spring Boot 2 (七):Spring Boot 如何解决项目启动时初始化资源 在项目启动的时候需要做一些初始化的操作,比如初始化线程池,提前加载好加密证书等.今天就给大家介绍一个 Spri ...
- 13 数组 Java内存分析 三种初始化
Java内存分析 三种初始化 静态初始化 //静态初始化 创建+赋值 int[] a = {1,2,3}; Man[] mans = {new Man(1,1),new Man(2,2)}; 动态初始 ...
- dpdk 代码分析一 : 内存初始化
一 前言 http://www.dpdk.org/ dpdk 是 intel 开发的x86芯片上用于高性能网络处理的基础库,业内比较常用的模式是linux-app模式,即 利用该基础库,在用户层空 ...
- ok6410内存初始化
•DRAM:它的基本原件是小电容,电容可以在两个极板上保留电荷,但是需要定期的充电(刷新),否则数据会丢失.缺点:由于要定期刷新存储介质,存取速度较慢. •SRAM:它是一种具有静止存取功能的内存,不 ...
- 第3阶段——内核启动分析之start_kernel初始化函数(5)
内核启动分析之start_kernel初始化函数(init/main.c) stext函数启动内核后,就开始进入start_kernel初始化各个函数, 下面只是浅尝辄止的描述一下函数的功能,很多函数 ...
- Linux内存初始化(四) 创建系统内存地址映射
一.前言 经过内存初始化代码分析(一)和内存初始化代码分析(二)的过渡,我们终于来到了内存初始化的核心部分:paging_init.当然本文不能全部解析完该函数(那需要的篇幅太长了),我们只关注创建系 ...
- Linux内存初始化(一)
一.前言 一直以来,我都非常着迷于两种电影拍摄手法:一种是慢镜头,将每一个细节全方位的展现给观众.另外一种就是快镜头,多半是反应一个时代的变迁,从非常长的时间段中,截取几个典型的snapshot,合成 ...
随机推荐
- clang -O3 for循环的LLVM IR
O3都是怪物,这里分析的是CLANG怪物,示例程序遍历数组每个元素然后放大. void foreach_scale(int arr[],int elem){ for(int i=0;i<elem ...
- EF core 学习 执行原生sql语句 之ExecuteReader 和ExecuteScalar
通过ef core 源码分析 Microsoft.EntityFrameworkCore.Storage.RelationalCommandExtensions类中有相应的方法 为此得到相应的结果: ...
- 牛客国庆集训day5 G 贵族用户 (模拟)
链接:https://www.nowcoder.com/acm/contest/205/G来源:牛客网 题目描述 终于活成了自己讨厌的样子. 充钱能让你变得更强. 在暖婊这个游戏里面,如果你充了x元钱 ...
- Java基础笔记(十九)——抽象类abstract
抽象类作为父类,不能实例化自己类型的对象,但可以通过向上转型实例化子类对象. public abstract class Animal{ } 比如eat(); ,每个动物子类都应有自己的方法,那An ...
- POJ 3252 区间内一个数的二进制中0的数量要不能少于1的数量(数位DP)
题意:求区间内二进制中0的数量要不能少于1的数量 分析:很明显的是数位DP: 菜鸟me : 整体上是和数位dp模板差不多的 , 需要注意的是这里有前导零的影响 , 所以需要在dfs()里面增加zor ...
- NETSpider 网络蜘蛛采集工具
NETSpider网站数据采集软件是一款基于.Net平台的开源软件.软件部分功能是基本Soukey软件进行开发的.这个版本采用VS2010+.NET3.5进行开发的.NETSpider采摘当前提供的主 ...
- HTTP的请求头标签 If-Modified-Since
一直以来没有留意过HTTP请求头的IMS(If-Modified-Since)标签. 最近在分析Squid的access.log日志文件时,发现了一个现象.就是即使是对同一个文件进行HTTP请求,第一 ...
- shell 命令下载软件 安装软件
下载命令:wget URL地址 wget http://mirrors.163.com/centos/6/os/x86_64/Packages/yum-3.2.29-81.el6.centos.noa ...
- VBS 操作Excel
VBS操作Excel 打开excel Dim objExcel,objWorkbook,objSheet Set objExcel=CreateObject("excel.applicati ...
- 利用划分树求解整数区间内第K大的值
如何快速求出(在log2n的时间复杂度内)整数区间[x,y]中第k大的值(x<=k<=y)? 其实我刚开始想的是用快排来查找,但是其实这样是不行的,因为会破坏原序列,就算另外一个数组来存储 ...