第四章之内存初始化

1,既然UART可以打印出信息来,那我们可以打印内存中的值。在506行添加如下代码:

 1
 2     /***UART transmit function by xu ***/
 3 display_addr_dat:
 4
 5     ldr r0,[r0]
 6
 7     ldr r1,=0xE2900020
 8
 9     ldr r2,=0x30
10     str r2,[r1]     @UTXH0=‘0‘
11
12     ldr r2,=0x78
13     str r2,[r1]     @UTXH0=‘x‘
14
15     ldr r3,=28
16
17 display_loop_count:
18     lsr r2,r0,r3    @logical shift right 28 bit
19     and r2,r2,#0xF
20
21     cmp r2,#10      @cmp r2 is mi or pl 10
22     addmi r2,r2,#0x30  @r2 is 1----9
23     addpl r2,r2,#0x37  @r2 is A----F
24     str r2,[r1]
25
26     sub r3,r3,#4
27     cmp r3,#0
28     bpl display_loop_count
29
30     ldr r2,=0xa
31     str r2,[r1]     @UTXH0=‘\r‘
32
33     ldr r2,=0xd
34     str r2,[r1]     @UTXH0=‘\n‘
35
36     mov pc, lr

如图:

2,这样我们可以进行测试,在216行,进行添加执行代码,如图:

我们通过手册查询可以得知内存地址oxE000_0000的值为0x43110020。那么重新编译和烧写一下u-boot.bin,看看串口输

出的信息与我们查询的值是否相同。

3,接一下来,我们来自己编写板子的内存初始化代码,可以根据厂家的光盘中裸机代码/src/cdram/memory.S中的代码做相应的

更改。代码如下:

  1 /*** ddrmem initialze by xu***/
  2 .globl ddrmem_init
  3 ddrmem_init:
  4
  5 #define ELFIN_GPIO_BASE            0xE0200000
  6 #define APB_DMC_0_BASE            0xF0000000
  7 #define DMC_CONCONTROL             0x00
  8 #define DMC_MEMCONTROL             0x04
  9 #define DMC_MEMCONFIG0             0x08
 10 #define DMC_DIRECTCMD             0x10
 11 #define DMC_PRECHCONFIG         0x14
 12 #define DMC_PHYCONTROL0         0x18
 13 #define DMC_PHYCONTROL1         0x1C
 14 #define DMC_RESERVED             0x20
 15 #define DMC_PWRDNCONFIG         0x28
 16 #define DMC_TIMINGAREF             0x30
 17 #define DMC_TIMINGROW             0x34
 18 #define DMC_TIMINGDATA             0x38
 19 #define DMC_TIMINGPOWER         0x3C
 20 #define DMC_PHYSTATUS             0x40
 21 #define DMC_CHIP0STATUS         0x48
 22 #define DMC_AREFSTATUS             0x50
 23 #define DMC_MRSTATUS             0x54
 24 #define DMC_PHYTEST0             0x58
 25     //初始化PHY DLL
 26     ldr r0, =APB_DMC_0_BASE
 27     //step 2 set PhyControl0.ctrl_start_point PhyControl0.ctrl_inc PhyControl0.ctrl_dll_on bit field to 1
 28     ldr r1, =0x0010100A
 29     str r1, [r0,#DMC_PHYCONTROL0]
 30
 31     //step 3 set PhyControl1.ctrl_shiftc PhyControl1.ctrl_ctrl_offsetc
 32     ldr r1, =0x00000086
 33     str r1, [r0,#DMC_PHYCONTROL1]
 34
 35     //step 4 set PhyControl0.ctrl_start bit-field to 1 DLL on
 36     ldr r1, =0x0010100B
 37     str r1, [r0,#DMC_PHYCONTROL0]
 38
 39 find_lock_val:
 40     //step 11 loop until DLL is locked
 41     ldr r1, [r0,#DMC_PHYSTATUS]
 42     and r2, r1,#0x7
 43     cmp r2, #0x7
 44     bne find_lock_val
 45
 46     //setp 12 Force value looking
 47     and r1, #0x3fc0
 48     mov r2, r1, LSL #18
 49     orr r2, r2, #0x100000
 50     orr r2, r2, #0x1000
 51     orr r1, r2, #0xB
 52     str r1, [r0,#DMC_PHYCONTROL0]
 53
 54     //初始化DMC0
 55     //step 5 set ConControl
 56     ldr r1, =0x0FFF1010
 57     str r1, [r0,#DMC_CONCONTROL]
 58
 59     //step 6 set MemControl
 60     ldr r1, =0x00202400
 61     str r1, [r0,#DMC_MEMCONTROL]
 62
 63     //step 7 set MemConfig0 512M config,8 banks
 64     ldr r1, =0x20E00323
 65     str r1, [r0,#DMC_MEMCONFIG0]
 66
 67     //step 8/1 set PrechConfig
 68     ldr r1, =0xFF000000
 69     str r1, [r0,#DMC_PRECHCONFIG]
 70
 71     //step 9/1 set TimingAref t_refi=7.5us * 133MHz=1038(0x40E)
 72     ldr r1, =0x0000040E
 73     str r1, [r0,#DMC_TIMINGAREF]
 74     //step 9/2 set TimingRow tRAS=45ns tRC=60ns tRCD=15ns tRP=15ns tRRD=7.5ns tRFC=127.5ns
 75     ldr r1, =0x11122206
 76     str r1, [r0,#DMC_TIMINGROW]
 77     //step 9/3 set TimingData tWTR=7.5ns tWR=15ns tRTP=7.5ns cl=4
 78     ldr r1, =0x12140000
 79     str r1, [r0,#DMC_TIMINGDATA]
 80     //step 9/4 set TimingPower t_mrd>=tMRD=2nCK t_cke<=tCKE=3nCK t_xp>=tXP=2nCK tXSRD=200ns tFAW=35ns
 81     ldr r1, =0x05DC0343
 82     str r1, [r0,#DMC_TIMINGPOWER]
 83
 84     //初始化DDR2 DRAM
 85     //step 14 lssue a "NOP" for DirectCmd and hold CKE to high level
 86     ldr r1, =0x07000000
 87     str r1, [r0,#DMC_DIRECTCMD]
 88
 89     //step 16 lssue a "PALL" for DirectCmd
 90     ldr r1, =0x01000000
 91     str r1, [r0,#DMC_DIRECTCMD]
 92
 93     //step 17 lssue an "EMRS2" for DirectCmd
 94     ldr r1, =0x00020000
 95     str r1, [r0,#DMC_DIRECTCMD]
 96
 97     //step 18 lssue an "EMRS3" for DirectCmd
 98     ldr r1, =0x00030000
 99     str r1, [r0,#DMC_DIRECTCMD]
100
101     //step 19 lssue an "EMRS" for DirectCmd and enable DLLs enable DQS
102     ldr r1, =0x00010000
103     str r1, [r0,#DMC_DIRECTCMD]
104
105     //step 20 lssue a "MRS" for DirectCmd and reset DLL
106     ldr r1, =0x00000542
107     str r1, [r0,#DMC_DIRECTCMD]
108
109     //step 21 lssue a "PALL" for DirectCmd
110     ldr r1, =0x01000000
111     str r1, [r0,#DMC_DIRECTCMD]
112
113     //step 22 lssue two "Auto Refresh" for DirectCmd
114     ldr r1, =0x05000000
115     str r1,[r0,#DMC_DIRECTCMD]
116
117     ldr r1, =0x05000000
118     str r1,[r0,#DMC_DIRECTCMD]
119
120     //step 23 lssue a "MRS" for DirectCmd and without reseting DLL
121     ldr r1, =0x00000442
122     str r1, [r0,#DMC_DIRECTCMD]
123
124     //step 25 lssue an "EMRS" for DirectCmd  set OCD Calibration Default and exit OCD Calibration
125     ldr r1, =0x00010380
126     str r1, [r0,#DMC_DIRECTCMD]
127
128     ldr r1, =0x00010000
129     str r1, [r0,#DMC_DIRECTCMD]
130
131     //step 27 set ConControl and turn on "auot refresh"
132     ldr r1, =0x0FF01030
133     str r1, [r0,#DMC_CONCONTROL]
134
135     //step 8/2 set PwrdnConfig
136     ldr r1, =0xFFFF00FF
137     str r1, [r0,#DMC_PWRDNCONFIG]
138
139     //step 28 IF power down modes is required set MemControl
140     ldr r1, =0x00202400
141     str r1, [r0,#DMC_MEMCONTROL]
142
143     //putout URAT char "DDR IS OK!"
144     ldr r0, =0xE2900020
145     ldr r1, =0x44    @UTH=‘D‘
146     str r1, [r0]
147
148     ldr r1, =0x44
149     str r1, [r0]     @UTH=‘D‘
150
151     ldr r1, =0x52
152     str r1, [r0]     @UTH=‘R‘
153
154     ldr r1, =0x20
155     str r1, [r0]     @UTH=‘ ‘
156
157     ldr r1, =0x49
158     str r1, [r0]     @UTH=‘I‘
159
160     ldr r1, =0x53
161     str r1, [r0]     @UTH=‘S‘
162
163     ldr r1, =0x20
164     str r1, [r0]     @UTH=‘ ‘
165
166     ldr r1, =0x4f
167     str r1, [r0]     @UTH=‘O‘
168
169     ldr r1, =0x4b
170     str r1, [r0]     @UTH=‘K‘
171
172     ldr r1, =0x21
173     str r1, [r0]    @UTH=‘!‘
174
175     ldr r1,    =0xa
176     str r1,    [r0]     @UTXH0=‘\r‘
177
178     ldr r1,    =0xd
179     str r1,    [r0]     @UTXH0=‘\n‘
180
181     mov pc, lr

4,在UART执行代码下面添加内存初始化执行代码220-221行。如图:

5,内存初始化完成,但是我们不知道内存初始化是否正确,这就需要验证。通过内存读取数据代码来进行验证222行-225行。如图所示:

6,然后,进行make,烧写u-boot.bin.然后可以看到串口输出信息中,输出与我们输入相同的内存地址的值

时间: 2024-10-02 18:28:24

第四章之内存初始化的相关文章

【嵌入式开发】裸机引导操作系统和ARM 内存操作 ( DRAM SRAM 类型 简介 | Logical Bank | 内存地址空间介绍 | 内存芯片连接方式 | 内存初始化 | 汇编代码示例 )

[嵌入式开发]ARM 内存操作 ( DRAM SRAM 类型 简介 | Logical Bank | 内存地址空间介绍 | 内存芯片连接方式 | 内存初始化 | 汇编代码示例 ) 一. 内存 简介 1. 两大内存分类 ( 1 ) DRAM 简介 ( 定期刷新 | 速度慢 | 成本低 ) DRAM 简介 : 1.硬件描述 : DRAM 基本由一个个小电容基本原件组成, 电容的两端保留电荷; 2.优缺点描述 : ① 优点 : 成本很低, 很便宜; ② 缺点 : 需要 定期刷新数据, 速度较慢; a.

第四章—变量,作用域和内存问题(二)

第四章-变量,作用域和内存问题(二) JS没有块级作用域 js没有块级作用域,这个概念容易导致误解,这里就区分下几个情况,大家好好参考下: 我们知道,在其他类C的语言中,由花挂号封闭的代码块都有自己的作用域.但是在JS中,却没有块级作用域: 这里if(true){}代表条件永真,永远执行这条.if(false){}的话就是永远不执行这条. 这个代码执行之后,在if语句定义的变量,在if语句外可以访问的到.在if语句中的变量声明会将变量添加到当前的执行环境中(这里是全局环境). 还有如下的两个例子

第四章 类加载机制

注:本文主要参考自<深入理解java虚拟机(第二版)> 在查看本文前,先要了解JVM内存结构,见 第一章 JVM内存结构 1.类加载流程 把描述类的数据从xxx.class文件加载到JVM内存 对这些数据进行校验.准备.解析(这三个过程总称为"链接") 对这些数据进行初始化,最终形成可被JVM直接使用的Class对象 注意: 类加载过程是在运行期完成的 2.加载 作用:把描述类的数据从xxx.class文件加载到JVM内存 此阶段完成三件事 通过一个类的全限定类名来获取定义

第四章 初步进入linux世界

第四章 初步进入linux世界 [Linux 系统启动过程] Linux的启动其实和windows的启动过程很类似,不过windows我们是无法看到启动信息的,而linux启动时我们会看到许多启动信息,例如某个服务是否启动. Linux系统的启动过程大体上可分为五部分:内核的引导:运行init:系统初始化:建立终端 :用户登录系统. A 内核引导 当计算机打开电源后,首先是BIOS开机自检,按照BIOS中设置的启动设备(通常是硬盘)来启动.紧接着由启动设备上的grub程序开始引导linux,当引

第四章 复合类型

第四章  复合类型 4.1  数组 4.1.1  数组简介 数组(array)是一种数据格式,能够存储多个同类型的值. 声明数组的通用格式如下: typeName arrayName[arraySize]; 表达式arraySize指定数组的元素数目,它只能是以下三种情况之一: 1)        整型常数(如10,枚举值也可以): 2)        const值 3)        常量表达式(如8 * sizeof(int)) 注意:使用数组要注意下标的正确.编译器不会检查使用的下标是否有

《Linux内核设计与实现》第四章学习笔记

第四章 进程调度 [学习时间:1小时45分 撰写博客时间:2小时10分钟] [学习内容:Linux的进程调度实现.抢占和上下文切换.与调度相关的系统调用] 调度程序负责决定将哪个进程投入运行,何时运行以及运行多长时间.进程调度程序可看做在可运行态进程之间分配有限的处理器时间资源的内核子系统. 最大限度利用处理器时间的原则:只要有可以执行的进程,那么总会有程序正在执行. 一.多任务 1.概念:多任务操作系统就是能同时并发地交互执行多个进程的操作系统,在单处理器机器上这会产生多个进程在同时运行的幻觉

C++ Primer Plus学习:第四章

C++入门第四章:复合类型 1 数组 数组(array)是一种数据格式,能够存储多个同类型的值. 使用数组前,首先要声明.声明包括三个方面: 存储每个元素中值的类型 数组名 数组中的元素个数 声明的通用风格如下: typename arrayname[arrysize]; 注;arrysize指定元素数目,必须是整型常量,不能是变量. 数组的很多用途均基于这样一个事实:可以单独访问数组元素.方法是使用下表或索引对元素进行编号.C++数组从0开始编号,并使用带索引的方括号表示法来指定数组元素. 注

《Linux内核设计与实现》第八周学习总结——第四章 进程调度

<Linux内核设计与实现>第八周学习总结——第四章 进程调度 第4章 进程调度35 调度程序负责决定将哪个进程投入运行,何时运行以及运行多长时间,进程调度程序可看做在可运行态进程之间分配有限的处理器时间资源的内核子系统.只有通过调度程序的合理调度,系统资源才能最大限度地发挥作用,多进程才会有并发行的效果. 调度程序没有太复杂的原理,最大限度地利用处理器时间的原则是只要有可以执行的进程,那么就总会有进程正在执行,但是只要系统中可运行的进程的数目比处理器的个数多,就注定某一给定时刻会有一些进程不

JS复习:第三章&amp;第四章

第三章 一.把一个值转换成字符串的两种方法: 1.使用每个值都有的toString( )方法.这个方法唯一要做的就是返回相应值的字符串表现.例如: var age = 11 ; var ageAsString = age.toString( ) ;       //字符串”11” var found = true ; var foundAsString = found.toString( ) ;    //字符串”true” 2.在不知道要转换的值是不是null或undefined的情况下,还可