S3C2440的裸奔--内存篇(非MMU)--------转的网友 泠瑛 的博客文章在此谢过!
S3C2440的裸奔 --内存篇
作者: 泠瑛 网名: ling 邮件: lingying<at>live.com qq: 1641445037 网络团队: ARELY小组 更新日期:2012年07月21日 星期六 20时06分05秒
声明: 这是我个人学习ARM2440的笔记,主要参考了下面这些书,当然还远远不止这些。互联网上的开源技术资料和老师学长的指导都是我学习的源泉,当然ARELY小组的哥哥姐姐更是给予我全方位的支持,尤其是何君哥哥,他给予我的不仅是技术上的,还有精神上的鼓励和引导,谢谢大家,感谢开源文化! 参考书目: 人民邮电出版社 《嵌入式Linux应用开发完全手册》 --韦东山著 机械工业出版社 《嵌入式Linux应用开发全程解析与实战》 --吴士力、刘奇、朱兰著 电子工业出版社 《嵌入式Linux系统实用开发》 --何永琪等著 人民邮电出版社 《Linux设备驱动开发详解》 --宋宝华著 电子工业出版社 《ARM嵌入式常用模块与综合系统设计实例精讲》--张绮文、解书钢著 电子工业出版社 《嵌入式系统Linux内核开发实战指南》 --王洪辉著 北京航空航天大学出版社 《ARM LINUX入门与实践》 --方强、程昌南著 北京航空航天大学出版社 《嵌入式底层软件开发》 --杨铸、唐攀著
记得以前在手机上玩推箱子,有些关卡难到我头痛,于是郁闷、气急败坏,甚至会有丢手机的冲动,世界那么 大,为什么要在规定的小空间里和自己过不去呢!开发板上也一样,之前一直在一个4K大的Stepping stone里打转转, 可惜了那64MB的内存了。那么,今天就到拥有更广阔的天地里折腾一番吧。
s3c2440对外引出了27根地址线ADDR0~ADDR26,最多能寻址2的27次方,也就是128MB,但实际上s3c2440能够 寻址1G的地址空间,这是因为它还有8根片选信号线nGCS0~nGCS7,每根信号线对应一个128MB地址空间,这个空间被称作 BANK,所以s3c2440共有8个BANK -- BANK0~BANK7,当访问某个BANK时,其对应的nGCS信号引脚电平拉低,这和单 片机上的扩展IO的操作类同。s3c2440是32位的芯片,理论上支持2的32次方,即4GB的地址空间,除去上面8个BANK用掉的 1GB地址空间外,特殊功能寄存器占用了0x48000000~0x5b00001c这段地址空间,其它的地址空间没有被使用。 BANK0~BANK5可以连接ROM和SRAM类型的存储器,BANK6~BANK7可以连接ROM、SRAM、SDRAM类型的存储器, 最大支持256MB,mini2440将两片32MB,16bits位宽的SDRAM连接在了BANK6和BANK7上,并联构成64MB、32位宽的 内存。
在处理SDRAM内部的数据时需要先指定行,再指定列,即可访问到需要的数据,由行和列构成的矩阵称为存储阵列, 大家一般会把它叫作"L-BANK",但SDRAM里面不会只有一个存储阵列,这是因为如果只做一个存储阵列会造成严重的寻址 冲突并大幅度降低内存效率。所以一般人们都将内存分为4个存储阵列(这也是SDRAM规范中的最高L-BANK数量),访问时 每次只能访问一个,具体访问那个L-BANK可以通过内存的两个外接引脚BA0和BA1来决定,mini2440将addr24连接BA0、 addr25连接BA1,通过地址线24和地址线25来选择存储单元的4个L-BANK。
SDRAM只有13根地址线A0~A12,只能寻址8MB(2的13次方)的内存空间,由于每个内存内部划分成四个L-BANK,所以 通过addr24和addr25的配合,就可以寻址一个内存芯片的全部空间。开发板上一共有两片并联的32MB的SDRAM,每发送一次 地址信号,两片芯片都可以同时接收到,之后其中一片返回低16bits的数据,另一片返回高16bits的数据。下面是内存芯片和 cpu的引脚的连接表:
-------------------------------------------------------------------------------------------------------------------- cpu引脚 内存芯片引脚 描述 -------------------------------------------------------------------------------------------------------------------- A2~A14 A0~A12 地址线 -------------------------------------------------------------------------------------------------------------------- D0~D31 DQ0~DQ31 数据线,其中一片的DQ0~DQ15连接D0~D15,另一片的DQ0~DQ15连接D16~D31 -------------------------------------------------------------------------------------------------------------------- A24,A25 BA0,BA1 L-BANK选择信号 -------------------------------------------------------------------------------------------------------------------- DQM0~DQM3 LDQM,UDQM 高低字节数据掩码信号 -------------------------------------------------------------------------------------------------------------------- SCKE SCKE 输入时钟有效信号 -------------------------------------------------------------------------------------------------------------------- SCLK SCLK 输入时钟 -------------------------------------------------------------------------------------------------------------------- nSCS0 nSCS 片选信号(和nGCS6是同一个引脚,只是功能不同) -------------------------------------------------------------------------------------------------------------------- nSRAS nSRAS 行地址选通信号 -------------------------------------------------------------------------------------------------------------------- nSCAS nSCAS 列地址选通信号 -------------------------------------------------------------------------------------------------------------------- nWE nWE 写入有效信号 --------------------------------------------------------------------------------------------------------------------
存储控制器的寄存器部分这里略过。
下面是启动代码:
@************************************************************************* @ File:head.S @ 功能:关闭看门狗,初始化时钟,初始化内存,将Stepping stone的数据 @复制到SDRAM, 然后跳到内存中继续运行main函数,循环点亮led灯。 @************************************************************************* @看门狗寄存器 .equ WTCON, 0x53000000 @看门狗控制寄存器 .equ WTDAT, 0x53000004 @看门狗数据寄存器 .equ WTCNT, 0x53000008 @看门狗计数寄存器@系统时钟寄存器 .equ LOCKTIME, 0x4c000000 @变频锁定时间寄存器 .equ MPLLCON, 0x4c000004 @MPLL寄存器 .equ CLKDIVN, 0x4c000014 @分频比寄存器@内存寄存器 .equ MEM_CTL_BASE, 0x48000000 .equ SDRAM_BASE, 0x30000000 @定义64MB内存开始的地址 .equ SDRAM_END, 0x34000000 @定义64MB内存结束的地址.text .global _start _start:bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启bl init_clock @初始化系统时钟bl memsetup @ 设置存储控制器bl copy2sdram @ 复制代码到SDRAM中ldr pc, =on_sdram @ 跳到SDRAM中继续执行 on_sdram:ldr sp, =SDRAM_END @ 设置堆栈,堆栈由高地址向低地址生长bl main halt_loop:b halt_loopdisable_watch_dog:mov r1, #WTCONmov r2, #0x0 @ 往WATCHDOG寄存器写0即可str r2, [r1]mov pc, lr @ 返回init_clock:@ 设置锁频时间ldr r0, =LOCKTIME @取得LOCKTIME寄存器地址ldr r1, =0x00ffffff @设置锁定时间str r1, [r0] @将r1中的数据写入r0 @设置FCLK,HCLK,PCLK三者之间的比例,本来还需要设置CAMDIVN寄存器,@但这里设置成1:4:8,所以CAMDIVN使用默认值就可以了!ldr r0, =CLKDIVN @取得CLKDIVN寄存器地址mov r1, #0x05 @设定比例str r1, [r0] @修改CPU总线模式mrc p15, 0, r1, c1, c0, 0orr r1, r1, #0xc0000000mcr p15, 0, r1, c1, c0, 0@倍频到400MHz ldr r0, =MPLLCON @MPLL控制寄存器ldr r1, =0x0005c011str r1, [r0]mov pc, lr @ 返回copy2sdram:@ 将Steppingstone的4K数据全部复制到SDRAM中去@ Steppingstone起始地址为0x00000000,SDRAM中起始地址为0x30000000mov r1, #0ldr r2, =SDRAM_BASEmov r3, #4*1024 copyloop: ldr r4, [r1],#4 @ 从Steppingstone读取4字节的数据,并让源地址加4str r4, [r2],#4 @ 将此4字节的数据复制到SDRAM中,并让目地地址加4cmp r1, r3 @ 判断是否完成:源地址等于Steppingstone的未地址?bne copyloop @ 若没有复制完,继续mov pc, lr @ 返回memsetup:@ 设置存储控制器以便使用SDRAM等外设mov r1, #MEM_CTL_BASE @ 存储控制器的13个寄存器的开始地址adrl r2, mem_cfg_val @ 这13个值的起始存储地址add r3, r1, #52 @ 13*4 = 54 initmemloop: ldr r4, [r2], #4 @ 读取设置值,并让r2加4str r4, [r1], #4 @ 将此值写入寄存器,并让r1加4cmp r1, r3 @ 判断是否设置完所有13个寄存器bne initmemloop @ 若没有写成,继续mov pc, lr @ 返回@4字节对齐 .align 4 mem_cfg_val:@ 存储控制器13个寄存器的设置值.long 0x22000000 @ BWSCON.long 0x00000700 @ BANKCON0.long 0x00000700 @ BANKCON1.long 0x00000700 @ BANKCON2.long 0x00000700 @ BANKCON3 .long 0x00000700 @ BANKCON4.long 0x00000700 @ BANKCON5.long 0x00018005 @ BANKCON6.long 0x00018005 @ BANKCON7.long 0x008E04F5 @ REFRESH.long 0x000000B1 @ BANKSIZE.long 0x00000030 @ MRSRB6.long 0x00000030 @ MRSRB7 @******************************************************************************
C程序还是使用上次那个leds.c程序,这里就不再列出代码了! 然后是编译用的Makefile.
#****************************************************************************** #Makefile #****************************************************************************** sdram.bin : head.S leds.carm-linux-gcc -c -o head.o head.Sarm-linux-gcc -c -o leds.o leds.carm-linux-ld -Ttext 0x30000000 head.o leds.o -o sdram_elfarm-linux-objcopy -O binary -S sdram_elf sdram.binarm-linux-objdump -D -m arm sdram_elf > sdram.dis clean:rm -f sdram.dis sdram.bin sdram_elf *.o #******************************************************************************
编译之后得到sdram.bin,下载到开发板上运行。可以看到led闪烁的速度比上次慢了很多, 这是因为外部的SDRAM的性能比内部的SRAM差很多。但内部的SRAM只有4k,如果程序大于4k, 就需要想办法将存储在NAND中的代码复制到SDRAM中去运行。 注意:上面的代码只是把SRAM中的代码复制到SDRAM中运行,并不是将NAND Flash中的 代码复制到SDRAM中运行,处理器启动后自动将NAND Flash中的前4K复制到内部SRAM中, 关于这一点,原先我理解错了,谢谢哥哥纠正。
转载于:https://www.cnblogs.com/tureno/articles/2690173.html
S3C2440的裸奔--内存篇(非MMU)--------转的网友 泠瑛 的博客文章在此谢过!相关推荐
- HelloDjango 第 08 篇:开发博客文章详情页
作者:HelloGitHub-追梦人物 文中涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 首页展示的是所有文章的列表,当用户看到感兴趣的文章时,他点击文章的标题或者继续阅读的按 ...
- 将socket设置为非阻塞(non-blocking) - 艾子的日志 - 网易博客
将socket设置为非阻塞(non-blocking) - 艾子的日志 - 网易博客 将socket设置为非阻塞(non-blocking) 2011-02-17 22:36:51| 分类: 默认分 ...
- wordpress html音乐,给你的WordPress博客文章中插入背景音乐的方法(纯代码,非插件)...
前一段时间,我分享了在WordPress文章日志中插入音频MP3(纯代码,免插件)这篇文件 ,曾介绍过如何在wordpress文章中加入MP3音频,今天要说的和这个基本相同.只不过上个文章中的MP3是 ...
- 我的第一篇CSDN博客文章
我的第一篇CSDN博客文章 今天是2016-08-30,作为一个临近毕业的在校大学生,马上就要开始九月份的找工作了,这两年在学校里面凭借兴趣以及专业方面的点点滴滴,决定了基本就从事IT编程这方面的工作 ...
- 零基础怎么写好一篇博客文章
大家好,我是csdn的博主:lqj_本人 现在是一名大二的学生. 我很荣幸被CSDN选为2023年的新星计划.小程序开发赛道的导师. 本人简介: 本人是2022年下半年开始进入CSDN开发者社区进行博 ...
- 如何写出一篇优秀的博客文章
如何写出一篇优秀的博客文章 在CSDN上,有很多人都想自己的文章受到浏览.关注.点赞以及评论.并且是越多越好,但是人那么多,如何使自己的文章被CSDN推荐至首页或者使自己的文章被搜索引擎排名出来,其中 ...
- 3. 在WordPress管理后台撰写第一篇博客文章
3. 发布第一篇博客文章 在前面的文章中,我们首先介绍了1. 购买云服务器和域名的基本操作,然后又成功2. 搭建最简单的博客网站,如果你还没完成上面这些操作,请提前点击查看. 这篇文章我们首先熟悉下网 ...
- 一篇高中生都能看懂的MySQL入门博客(长文)
写在前面: 本篇博客共一万五千字左右,是我自己对MySQL进行重新学习时写的,是一些偏基础的东西. 如果你对MySQL足够的了解,本篇博客最多只能起一个查漏补缺的作用. 博客的主要面向对象为:想学习了 ...
- python控制台中怎么控制开始和结束_Python-基础篇之控制台编程 - 随笔分类 - 梦并不遥远 - 博客园...
本章节主要包括Python的基础编程,面向过程和面向对象两种方法. 摘要:目录 [TOC] 前言 在此之前,我们以前写的编程,都是面向过程的编程,今儿起,我们开始学习一类编程的思想,也是相对面向过程更 ...
- java = 优化_Java9系列第7篇:Java.util.Optional优化与增强 - 字母哥博客 - 博客园
我计划在后续的一段时间内,写一系列关于java 9的文章,虽然java 9 不像Java 8或者Java 11那样的核心java版本,但是还是有很多的特性值得关注.期待您能关注我,我将把java 9 ...
最新文章
- 七十四、SpringBoot 的数据缓存cache(一)
- 从nginx的编译安装,了解编译安装原理
- Android 应用软件开发(九)控件续
- java json 易用_Java中 Json的使用
- 解构领域驱动设计(三):领域驱动设计
- 如何在Flutter上优雅地序列化一个对象
- html背景图片只显示一张图片,img只显示图片一部分 或 css设置背景图片只显示图片指定区域(示例代码)...
- win10文件同步到服务器失败,win10系统同步时间同步失败的解决方法
- carsim中质心加速度_Carsim整车建模参数.doc
- html视图查看,视图.html · zhaohaihang/Semantic UI demo - Gitee.com
- [总结]FDM 3D打印机DIY实践
- linux 解析elf文件格式,Linux下ELF文件解析
- ifconfig创建sit隧道
- transformer之预训练task小析(五)
- 左/右移运算符,循环左/右移运算
- uniapp小程序 安卓和ios时间兼容性问题解决方案
- 夏季繁华系列||妆面照欣赏
- 数据挖据---机器学习平台之H2O架构/接口/实践
- 数据分析之Excel的基本功能(下)
- Android手机的USB