31.6410内存的知识

31.6410内存的知识

6410的地址空间分布:

S3C6410处理器拥32位地址总线,其寻址空间为。其中高为保留外设区,低2GB区域又可划分为两部分:主存储区和外设区。

外设主要是寄存器所在的地址。

主存储区分为:Boot镜像区、内部存储区、静态存储区、保留区、动态存储区:

Boot镜像区:这个区域的作用正如它的名字所述,是用来启动ARM系统的。但是这个区域并没有固定的存储介质与之对应。而是通过修改启动选项,把不同的启动介质映射到该区域。比如说选择了IROM 启动方式后,就把IROM映射到该区域。

内部存储区:这个区域对应着内部的内存地址,iROM和SRAM都是分布在这个区间。0x08000000~0x0bffffff对应着内部ROM,但是IROM实际只有32KB,选择从IROM启动的时候,首先运行就是这里面的程序BL0,这部分代码由三星固化。0x0c000000~0x0fffffff对应内部SRAM,实际就是8KB的Steppingstone。

静态存储区:这个区域用于访问挂在外部总线上的设备,比如说NOR flash、oneNand等。这个区域被分割为6个bank,每个bank为128MB,数据宽度最大支持16bit,每个bank由片选Xm0CS[0]~Xm0CS[5] 选中。

动态存储区:该区域从0x50000000~0x6fffffff,又分为2个区间,分别占256MB,可以片选Xm1CS[0]~Xm1CS[1]来进行着2个区间的选择。我们开发板上的内存就安排在这 6410 256MB DDR个区域,这也就是为什么6410的内存地址是从0x50000000开始的原因。

6410的存储控制器:

S3C6410X.pdf的第五章是DRAM CONTROLLER:

1.Program memc_cmd to ‘3‘b100 which makes DRAM Controller enter ‘config‘ state.

2.Write memory timing parameter, chip configuration, and id configuration registers.

3.Wait 200us to allow SDRAM power and clock to stabilize. However, when CPU starts working, power and clock would already be stabilized.

4.Execute memory initialization sequence.

5.Program memc_cmd to ‘3‘b000 which makes DRAM Controller enter ‘Ready‘ state.

6.Check memory status field in memc_stat until memory status becomes ‘2‘bo1 ,which means ‘Ready‘.

从上面的描述知道,6410的存储控制器的初始化是要有流程的:(2440不需要)所以看看uboot里是如何来初始化存储控制器的。验证一下uboot是不是按照上面的步骤来的:

打开uboot/cpu/s3c64xx/s3c6410里的cpu_init.S:这个汇编文件就是进行板子的内存和存储控制器初始化的。

在这汇编文件的开头几行不知道是做什么的暂时不管:

,

从注释看到,这是在设置总线的大小。

芯片文档:

在该寄存器里主要的是看:

注意:DATA[26:16]改为DATA[31:16]

从上面知道,如果该寄存器的[7]位设置为0,那么DATA[31:16]这16位就作为内存芯片数据引脚。如果是1,则这些位就会被SROMC使用了,这是设置为0.

0xd=0b00001101,所以[7]=0的,所以是作为数据引脚的。

接着是:

可以看到有对应的数据出现了0x04=0b100,数据写入的寄存器是MEMC_CMD,这跟手册里是一致的:1.Program memc_cmd to ‘3‘b100 which makes DRAM Controller enter ‘config‘ state.

按照上面的操作:

寄存器MEMC_CMD:

2.Write memory timing parameter, chip configuration, and id configuration registers.这是进行写内存的时间参数,芯片配置,配置寄存器等一系列寄存器的配置操作:就不看了:

ldr    r1, =DMC_DDR_REFRESH_PRD

str    r1, [r0, #INDEX_DMC_REFRESH_PRD]

ldr    r1, =DMC_DDR_CAS_LATENCY

str    r1, [r0, #INDEX_DMC_CAS_LATENCY]

ldr    r1, =DMC_DDR_t_DQSS

str    r1, [r0, #INDEX_DMC_T_DQSS]

ldr    r1, =DMC_DDR_t_MRD

str    r1, [r0, #INDEX_DMC_T_MRD]

ldr    r1, =DMC_DDR_t_RAS

str    r1, [r0, #INDEX_DMC_T_RAS]

ldr    r1, =DMC_DDR_t_RC

str    r1, [r0, #INDEX_DMC_T_RC]

ldr    r1, =DMC_DDR_t_RCD

ldr    r2, =DMC_DDR_schedule_RCD

orr    r1, r1, r2

str    r1, [r0, #INDEX_DMC_T_RCD]

ldr    r1, =DMC_DDR_t_RFC

ldr    r2, =DMC_DDR_schedule_RFC

orr    r1, r1, r2

str    r1, [r0, #INDEX_DMC_T_RFC]

ldr    r1, =DMC_DDR_t_RP

ldr    r2, =DMC_DDR_schedule_RP

orr    r1, r1, r2

str    r1, [r0, #INDEX_DMC_T_RP]

ldr    r1, =DMC_DDR_t_RRD

str    r1, [r0, #INDEX_DMC_T_RRD]

ldr    r1, =DMC_DDR_t_WR

str    r1, [r0, #INDEX_DMC_T_WR]

ldr    r1, =DMC_DDR_t_WTR

str    r1, [r0, #INDEX_DMC_T_WTR]

ldr    r1, =DMC_DDR_t_XP

str    r1, [r0, #INDEX_DMC_T_XP]

ldr    r1, =DMC_DDR_t_XSR

str    r1, [r0, #INDEX_DMC_T_XSR]

ldr    r1, =DMC_DDR_t_ESR

str    r1, [r0, #INDEX_DMC_T_ESR]

ldr    r1, =DMC1_MEM_CFG

str    r1, [r0, #INDEX_DMC_MEMORY_CFG]

ldr    r1, =DMC1_MEM_CFG2

str    r1, [r0, #INDEX_DMC_MEMORY_CFG2]

ldr    r1, =DMC1_CHIP0_CFG

str    r1, [r0, #INDEX_DMC_CHIP_0_CFG]

ldr    r1, =DMC_DDR_32_CFG

str    r1, [r0, #INDEX_DMC_USER_CONFIG]

3.Wait 200us to allow SDRAM power and clock to stabilize. However, when CPU starts working, power and clock would already be stabilized.

在第三步这里,是可以不做的。跳过。

4.Execute memory initialization sequence.

是内存初始化执行序列:

1.Program mem_cmd in direct_cmd to ‘2‘b11 which makes DRAM Controller issue ‘NOP‘ memory command.

2.Program mem_cmd in direct_cmd to ‘2‘b00 which makes DRAM Controller issue ‘Prechargeall‘ memorycommand.

3.Program mem_cmd in direct_cmd to ‘2‘b01 which makes DRAM Controller issue ‘Autorefresh‘ memorycommand.

4.Program mem_cmd in direct_cmd to ‘2‘b11 which makes DRAM Controller issue ‘Autorefresh‘ memorycommand.

5.Program mem_cmd to ‘2‘b10 in direct_cmd, which makes DRAM Controller issue ‘MRS‘ memory command- Bank address for EMRS must be set.

6.Program mem_cmd to ‘2‘b10 in direct_cmd, which makes DRAM Controller issue ‘MRS‘ memory command.- Bank address for MRS must be set.

1.在这内存初始化系列的第一条是往direct_cmd寄存器的mem_cmd位写入b11,使DRAM控制寄存器发出一个NOP命令。(上面mem_cmd是01是错的,下面的才是对的)。

所以在DIRECTCMD寄存器里写入的是:0b11000000000000000000=0x000C0000.看看uboot里的代码:

可以看到uboot里是按照芯片手册写的,写入的也是0x0c0000.

2.Program mem_cmd in direct_cmd to ‘2‘b00 which makes DRAM Controller issue ‘Precharge all‘ memorycommand.

写入的值是0b00,也是对应的:

3和4.Program mem_cmd in direct_cmd to ‘2‘b01 which makes DRAM Controller issue ‘Autorefresh‘ memorycommand.

AutoRefresh写入的是0b01000000000000000000=0x40000,可以看到也是正确的。

5.Program mem_cmd to ‘2‘b10 in direct_cmd, which makes DRAM Controller issue ‘MRS‘ memory command- Bank address for EMRS must be set.

0x0a0000=0b10100000000000000000可以看到是往direct_cmd写入了10.

6.Program mem_cmd to ‘2‘b10 in direct_cmd, which makes DRAM Controller issue ‘MRS‘ memory command.- Bank address for MRS must be set.

0x080032=0b10000000000000110010, 可以看到是往direct_cmd写入了10.操作也是正确的。

到这里,uboot内存初始化完成,接下来是存储控制器的初始化:

5.Program memc_cmd to ‘3‘b000 which makes DRAM Controller enter ‘Ready‘ state.

6.Check memory status field in memc_stat until memory status becomes ‘2‘bo1 ,which means ‘Ready‘.

mem.S:

.text

.global mem_init

mem_init:

ldr r0, =0x7e00f120

mov r1, #0x8

str r1, [r0]

ldr r0, =0x7e001004 @内存控制命令寄存器

mov r1, #0x4 @根据手册得知需要先进入配置模式

str r1, [r0]

ldr r0, =0x7e001010 @刷新寄存器地址

ldr r1, =( ( 7800 / ( 1000000000/133000000 ) + 1 ) ) @设置刷新时间

str r1, [r0]

ldr r0, =0x7e001014 @CAS latency寄存器

mov r1, #(3 << 1)

str r1, [r0]

ldr r0, =0x7e001018 @t_DQSS寄存器

mov r1, #0x1

str r1, [r0]

ldr r0, =0x7e00101c @T_MRD寄存器

mov r1, #0x2

str r1, [r0]

ldr r0, =0x7e001020 @t_RAS寄存器

ldr r1, =( ( 45 / ( 1000000000 / 133000000 ) + 1 ) )

str r1, [r0]

ldr r0, =0x7e001024 @t_RC寄存器

ldr r1, =( ( 68 / ( 1000000000 / 133000000 ) + 1 ) )

str r1, [r0]

ldr r0, =0x7e001028 @t_RCD寄存器

ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) )

str r1, [r0]

ldr r0, =0x7e00102c @t_RFC寄存器

ldr r1, =( ( 80 / ( 1000000000 / 133000000 ) + 1 ) )

str r1, [r0]

ldr r0, =0x7e001030 @t_RP寄存器

ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) )

str r1, [r0]

ldr r0, =0x7e001034 @t_rrd寄存器

ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) )

str r1, [r0]

ldr r0, =0x7e001038 @t_wr寄存器

ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) )

@ ldr r2, [r0]

str r1, [r0]

ldr r0, =0x7e00103c @t_wtr寄存器

mov r1, #0x07

str r1, [r0]

ldr r0, =0x7e001040 @t_xp寄存器

mov r1, #0x02

str r1, [r0]

ldr r0, =0x7e001044 @t_xsr寄存器

ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) )

str r1, [r0]

ldr r0, =0x7e001048 @t_esr寄存器

ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) )

str r1, [r0]

ldr r0, =0x7e00100c @内存控制配置寄存器

ldr r1, =0x00010012 @配置控制器

str r1, [r0]

ldr r0, =0x7e00104c @32位DRAM配置控制寄存器

ldr r1, =0x0b45

str r1, [r0]

ldr r0, =0x7e001200 @片选寄存器

ldr r1, =0x150f8

str r1, [r0]

ldr r0, =0x7e001304 @用户配置寄存器

mov r1, #0x0

str r1, [r0]

ldr r0, =0x7e001008

ldr r1, =0x000c0000

str r1, [r0]

ldr r1, =0x00000000

str r1, [r0]

ldr r1, =0x00040000

str r1, [r0]

ldr r1, =0x000a0000

str r1, [r0]

ldr r1, =0x00080032

str r1, [r0]

ldr r0, =0x7e001004

mov r1, #0x0

str r1, [r0]

check_dmc1_ready:

ldr r0, =0x7e001000

ldr r1, [r0]

mov r2, #0x3

and r1, r1, r2

cmp r1, #0x1

bne check_dmc1_ready

nop

mov pc, lr

时间: 2024-10-10 14:00:44

31.6410内存的知识的相关文章

32.210内存的知识

32.210内存的知识 210可寻址的空间是4GB大小,内存的起始地址是20000000,前面知道2440使用的内存是SDRAM,6410使用的内存是DDR,这里210使用的是DDR2.在210的地址空间中零地址处跟6410一样也是映射镜像区,例如当选择从NandFlash启动的使用,就会把IROM的空间映射到0地址处. 内存芯片连接: 在2440和6410两款芯片中,它们的数据宽度是16bits,为了得到32bits的数据宽度,采用的是两片芯片级联的方式.而210采用的数据宽度是8bits的,

30.2440内存的知识

30.2440内存的知识 首先看2440的地址线:mini2440原理图.pdf 2440的芯片提供了27根地址线=128M. S3c2440芯片对外提供的引脚上,只给出了27根地址线addr[0:26].这27根引脚地址线,只能访问128M的外设空间. 为了扩大外设的访问范围,S3c2440芯片又提供了8个片选信号nGCS0~nGCS7.当某个片选信号nGCSx有效时,则可以通过27根地址线去访问对应这个片选的128MB空间.由于有8个片选,所以2440芯片能访问的外设空间总共为8*128MB

linux内存基础知识和相关调优方案

内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁.计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大.内存作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据.只要计算机在运行中,CPU就会把需要运算的数据调到内存中进行运算,当运算完成后CPU再将结果传送出来,内存的运行也决定了计算机的稳定运行.对于整个操作系统来说,内存可能是最麻烦的的设备.而其性能的好坏直接影响着整个操作系统. 我们知道CPU是不能与硬盘打交道的,只有数据被载入到内存中才可

每个Android开发者必须知道的内存管理知识

原文:每个Android开发者必须知道的内存管理知识 拷贝在此处,以备后续查看. 相信一步步走过来的Android从业者,每个人都会遇到OOM的情况.如何避免和防范OOM的出现,对于每一个程序员来说确实是一门必不可少的能力.今天我们就谈谈在Android平台下内存的管理之道,开始今天的主题之前,先再次回顾两个概念. 内存泄漏:对象在内存heap堆中中分配的空间,当不再使用或没有引用指向的情况下,仍不能被GC正常回收的情况.多数出现在不合理的编码情况下,比如在 Activity中注册了一个广播接收

SQL Server内存方面知识收集

浅谈SQL Server 对于内存的管理 http://www.cnblogs.com/CareySon/archive/2012/08/16/HowSQLServerManageMemory.html SQL Server内存方面知识收集

转:c/c++内存释放知识总结

转自:http://www.cnblogs.com/chuncn/archive/2011/04/12/2014273.html 基础知识:五大内存分区 栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区.里面的变量通常是局部变量.函数参数等. 堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete.如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收.(new char;  delete char;

Linux系统基本的内存管理知识讲解

内存是Linux内核所管理的最重要的资源之一.内存管理系统是操作系统中最为重要的部分,因为系统的物理内存总是少于系统所需要的内存数量.虚拟内存就是为了克服这个矛盾而采用的策略.系统的虚拟内存通过在各个进程之间共享内存而使系统看起来有多于实际内存的内存容量.Linux支持虚拟内存, 就是使用磁盘作为RAM的扩展,使可用内存相应地有效扩大.核心把当前不用的内存块存到硬盘,腾出内存给其他目的.当原来的内容又要使用时,再读回内存. 一.内存使用情况监测 (1)实时监控内存使用情况 在命令行使用“Free

内存基础知识

下面的列表总结了重要的 CLR 内存概念. 每个进程都有其自己单独的虚拟地址空间. 同一台计算机上的所有进程共享相同的物理内存,如果有页文件,则也共享页文件. 默认情况下,32 位计算机上的每个进程都具有 2 GB 的用户模式虚拟地址空间. 作为一名应用程序开发人员,你只能使用虚拟地址空间,请勿直接操控物理内存. 垃圾回收器为你分配和释放托管堆上的虚拟内存. 如果你编写的是本机代码,请使用 Win32 函数处理虚拟地址空间. 这些函数为你分配和释放本机堆上的虚拟内存. 虚拟内存有三种状态: 可用

iOS手动内存管理知识总结及发散思维

[版权声明] 此文版权归作者Vince Yuan (vince.yuan#gmail.com)所有.欢迎非营利性转载,转载时必须包含原始链接http://vinceyuan.cnblogs.com/,且必须包含此版权声明的完整内容. 版本 1.1  发表于2010-03-08 [注] 本文会以作者Vince Yuan的文章内容为基础,本人添加括号备注. 前言 初学objectice-C的朋友都有一个困惑,总觉得对objective-C的内存管理机制琢磨不透,程序经常内存泄漏或莫名其妙的崩溃.我在