9.内存的了解

发布者:EtherealHeart最新更新时间:2024-10-21 来源: cnblogs关键字:内存 手机看文章 扫描二维码
随时随地手机看文章

内存由于具备访问速度快,访问方式简单等优点,成为了PC或者是嵌入式硬件平台上不可或缺的元件。在开始学习如何使用内存之前,非常有必要先了解一下内存的分类:

    1.1内存分类:

1.2 DRAM分类

 

    2.内存内部结构:

    包括:表结构,L-Bank,寻址信息(包括L-Bank选择信号和行地址)。

    2.1表结构:

 

 

 

 

 

 

 

 

 

 

 

 

 

    2.2L-Bank的结构:

    2.3:寻址信息:

 

 

 

 

 

 

 

 

 

    6410内存初始化:

 

  1. 地址空间:

 

外设区是放寄存器的,主存储区又被分为五个子区:

 

 

 

 

 

1.1:主存储区-划分:

 

内存初始化

下面我们来完成内存初始化的工作:

图一

如图一,我们知道第一项工作是往我们的memc_cmd的域入b100,让我们的DRAM Controller进入config状态。这个域是在我们的P1MEMCCMD这个寄存器里面:

代码操作:

接下来是第二项工作:初始化以下的寄存器:

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

我们从上面知道。第三步是可以不做的:

接下来进入第四步:Execute memory initialization sequence.内存初始化系列:

由上面的图知道,第一件事是把direct_cmd寄存器相应的位写入b10,让它发出一个nop的指令。下面是该寄存器的地址:

 

上面知道,要让系统发出nop命令,18,19位是等于11的。上面的10是错的。其他的是0.所以我们只要往该寄存器的18,19位写入11即可:代码:

第二件事是往我们的direct_cmd相应的位写入00,让它发出prechargeall命令:

代码:

第三项工作:

连续两次:

第五项工作:

这个我们是参考uboot的参数的:

代码:

第五件事:这样就完成了我们的第四件事Execute memory initialization sequence,接下来是第五件事:Program memc_cmd to '3'b000', which makes DRAM Controller enter 'Ready' state.就是往我们的寄存器写入0,让我们的controller进入ready的状态:

第六件事就是检查是否ready了:

从文字知道,我们得去看memc_stat这个寄存器:

我们看到最低的两位,就是状态位,所以要检查最低两位的值是否为01:

 

 

其实到这里,我们内存的初始化还没完成,就是在开头的时候,我们的落下的那几行代码:

这是用来干什么的呢?我们来看看手册:

该寄存器最重要的是第7位:

上面应该是31-16位:当这一位是0的时候,

如果第7位是0,上面的16-31这16个pin角,就用来作为我们的数据线。若果是1,就被我们的SROMC使用的。所以这一位是设置为0.

这样就写好了:make:

下载到开发板,led亮起来。

中间的代码没有讲------对应的是如下 :自学:

 

 

下面是Uboot里的代码实现:uboot_ok6410/cpu/s3c64xx/s3c6410/cpu_init.S:

#include

#include

 

    .globl mem_ctrl_asm_init

mem_ctrl_asm_init:

    ldr    r0, =ELFIN_MEM_SYS_CFG            @Memory sussystem address 0x7e00f120

    mov    r1, #0xd                @ Xm0CSn2 = NFCON CS0, Xm0CSn3 = NFCON CS1

    str    r1, [r0]

 

    ldr    r0, =ELFIN_DMC1_BASE            @DMC1 base address 0x7e001000

 

    ldr    r1, =0x04

    str    r1, [r0, #INDEX_DMC_MEMC_CMD]

 

    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]

 

    @DMC0 DDR Chip 0 configuration direct command reg

    ldr    r1, =DMC_NOP0

    str    r1, [r0, #INDEX_DMC_DIRECT_CMD]

 

    @Precharge All

    ldr    r1, =DMC_PA0

    str    r1, [r0, #INDEX_DMC_DIRECT_CMD]

 

    @Auto Refresh    2 time

    ldr    r1, =DMC_AR0

    str    r1, [r0, #INDEX_DMC_DIRECT_CMD]

    str    r1, [r0, #INDEX_DMC_DIRECT_CMD]

 

    @MRS

    ldr    r1, =DMC_mDDR_EMR0

    str    r1, [r0, #INDEX_DMC_DIRECT_CMD]

 

    @Mode Reg

    ldr    r1, =DMC_mDDR_MR0

    str    r1, [r0, #INDEX_DMC_DIRECT_CMD]

 

#ifdef CONFIG_SMDK6410_X5A

    ldr    r1, =DMC1_CHIP1_CFG

    str    r1, [r0, #INDEX_DMC_CHIP_1_CFG]

 

    @DMC0 DDR Chip 0 configuration direct command reg

    ldr    r1, =DMC_NOP1

    str    r1, [r0, #INDEX_DMC_DIRECT_CMD]

 

    @Precharge All

    ldr    r1, =DMC_PA1

    str    r1, [r0, #INDEX_DMC_DIRECT_CMD]

 

    @Auto Refresh    2 time

    ldr    r1, =DMC_AR1

    str    r1, [r0, #INDEX_DMC_DIRECT_CMD]

    str    r1, [r0, #INDEX_DMC_DIRECT_CMD]

 

    @MRS

    ldr    r1, =DMC_mDDR_EMR1

    str    r1, [r0, #INDEX_DMC_DIRECT_CMD]

 

    @Mode Reg

    ldr    r1, =DMC_mDDR_MR1

    str    r1, [r0, #INDEX_DMC_DIRECT_CMD]

#endif

 

    @Enable DMC1

    mov    r1, #0x0

    str    r1, [r0, #INDEX_DMC_MEMC_CMD]

 

check_dmc1_ready:

    ldr    r1, [r0, #INDEX_DMC_MEMC_STATUS]

    mov    r2, #0x3

    and    r1, r1, r2

    cmp    r1, #0x1

    bne    check_dmc1_ready

    nop

mov    pc, lr

 

/* Below code is for ARM926EJS and ARM1026EJS */

    .globl cleanDCache

cleanDCache:

    mrc    p15, 0, pc, c7, c10, 3    /* test/clean D-Cache */

    bne    cleanDCache

    mov    pc, lr

 

    .globl cleanFlushDCache

cleanFlushDCache:

    mrc    p15, 0, pc, c7, c14, 3    /* test/cleanflush D-Cache */

    bne    cleanFlushDCache

    mov    pc, lr

 

    .globl cleanFlushCache

cleanFlushCache:

    mrc    p15, 0, pc, c7, c14, 3    /* test/cleanflush D-Cache */

    bne    cleanFlushCache

    mcr    p15, 0, r0, c7, c5, 0    /* flush I-Cache */

    mov    pc, lr

    .ltorg

 

 

 

 

[1] [2]
关键字:内存 引用地址:9.内存的了解

上一篇:8.时钟初始化
下一篇:android平台6410背光修改

推荐阅读最新更新时间:2026-03-20 11:58

Part8-不用内存怎么行_6410内存初始化lesson3
1、6410地址空间 外设区:从0x70000000-0x7FFFFFFF有256MB 主存储区:从0x00000000-0x6FFFFFFF有1972MB 对于主存储区: 静态存储区可以接我们的NOR Flash以及One nand等等设备,它的6*128MB意思是有6个BANK,每个BANK有128MB. 动态存储区:它的起始地址为0x50000000,是内存的起始地址,故我们把DDR的内存放到了动态存储区。 2、内存芯片硬件连接 用的两块128MB的芯片形成了256MB的内存容量。 3、芯片手册导读 打开芯片手册找到DRAM控制器章节, (注意2440对存储器控制器的初始化过程没有固定的顺序的!) 中文版芯片手册
[单片机]
Part8-不用<font color='red'>内存</font>怎么行_<font color='red'>6410</font><font color='red'>内存</font>初始化lesson3
6410支持256M内存的修改记录
1、更改C:WINCE600PLATFORMSMDK6410SRCINCMemParam_mDDR.inc ; 31th register in P1MEMCFG shoud be set as '0' to support one cke control DMC1_MEM_CFG EQU ((1 30)+(0 21)+(0 18)+(2 15)+(0 14)+(0 13)+(0 7)+(0 6)+(3 3)+(2 0)) ; colum A0~A9 2、 DMC1_CHIP0_CFG EQU ((1 16)+(0x50 8)+(0xF0 0)) ; BRC (Linear Addres
[单片机]
OK6410A 开发板 (八) 31 linux-5.11 OK6410A 感知linux的内存管理
linux 内存管理 , 我们感知三类内存管理 系统内存管理 A 内核线程内存管理 A 用户进程内存管理 内核态 A 用户态 B 这几种应该分为两类 , A B A 类共用一个内存(虚拟和物理) B 类每个进程有一个内存(虚拟和物理) 另外,我们知道在硬件上 内存是 物理内存 但在 linux 里面, 内存 除了物理内存 还包括 swap空间代表的空间(这里是将硬盘当作内存) // 可以从 free 命令 分析出来 A 系统内存管理的感知 系统启动的时候,会打印如下的信息 Memory: 243936K/262144K available (5120K kernel code,
[单片机]
OK6410A 开发板 (八) 35 linux-5.11 OK6410A 内存管理第三阶段
C setup_arch- paging_init- bootmem_init- memblock_allow_resize返回 - mm_init- mem_init返回 ----此时memblock消亡,buddy初始化完成,开启了基于虚拟内时代的 buddy内存管理器时代 流程 setup_arch(&command_line);- paging_init bootmem_init find_limits(&min_low_pfn, &max_low_pfn, &max_pfn); sparse_init zone_sizes_init(min_low_pfn, max_low_pfn, max_p
[单片机]
OK6410A 开发板 (八) 36 linux-5.11 OK6410A 内存管理第四阶段
D mm_init- mem_init返回 - mm_init- kmem_cache_init返回 ----此时slab建立,开启了基于 buddy内存管理器时代 的 slab内存管理器时代 kmem_cache_init 此过程以 slab 为基础,通过slab 的api kmem_cache_create , 创建 很多个 slab 假设这么多个slab 为 一个集合A 这么多slab 就是给用户用的,然后 这么多slab 的 alloc 和 free api 是什么呢? 针对某一个 slab, slab 提供了 kmem_cache_alloc 和 kmem_cache_free 那么
[单片机]
OK6410A 开发板 (八) 115 linux-5.11 OK6410A 内存文件系统的挂载实例
mount -t tmpfs tmpfs /work/mount/ struct mount 结构体 $1 = (struct mount *) 0x816f5780 // struct mount 结构体 地址 $2 = { // struct mount 结构体 内容 mnt_hash = { next = 0x0, pprev = 0x0 }, mnt_parent = 0x816f5780, // 表示挂载到了 /work/mount/ 所在的 struct mount 上 , 0x816f5780 为 /work/mount/ 所在的 struct mount 的地址 mnt_mo
[单片机]
OK6410A 开发板 (八) 122 linux-5.11 OK6410A 以linux用户角度去应用用户空间内存
以linux用户角度去应用用户空间内存 // 在 用户空间是以 段的形式管理的 在内核空间是通过 VMA 来管理这些段的 // https://blog.csdn.net/u011011827/article/details/117335579 中的 VMA 代码段内存 通过增加代码长度 通过汇编指定一个段为代码段(虽然里面可能是数据) 数据段内存 全局变量 // __attribute__((section( .ARM.__at_address ))) , 这个东西要该默认的连接脚本?//TODO 栈内存 局部变量 堆内存 level1 api: syscall
[单片机]
OK6410裸机片内内存中重定位代码
start.S源码: .globl _start _start: // 硬件相关的设置 // Peri port setup ldr r0, =0x70000000 orr r0, r0, #0x13 mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff) // 关看门狗 // 往WTCON(0x7E004000)写0 ldr r0, =0x7E004000 mov r1, #0 str r1, // 重定位 adr r0, _start // 伪指令,取_start的当前地址 ldr r1, =_start
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved