Tiny4412MMU内存管理
MMU是Memory Management Unit的缩写,中文名是内存管理单元,MMU是由ARM芯片中的cp15协处理器管理,它的作用是负责虚拟内存到物理内存的映射
要将虚拟内存映射为物理内存,就要需要构建一张映射表,那么如何来构建这张映射表将至关重要,目前,32位操作系统提供的虚拟存为4G,每个地址占16位4个字节,如果虚拟内存与物理内存要实现一一对应,那么这个张表的一条记录就要占用8个字节,整张表的大小就为32G,这肯定是不可取的;于是我们就采用另一种方法,我们将一个地址的前12为即2的12次方4k做为基地址,后20位作为偏移量,现在我们只需要将虚拟地址的前12位与物理地址的前12一一对应;这样每条记录8字节,整个表就变为32k,明显小了很多,那么我们在访问的时候就需要通过基地址找到所对应的物理地址然后加上偏移量即可(基地址 + 偏移量);
因此,假如我们需要将虚拟地址0x2ab45678映射到物理地址0x6ab45678,我们就可以先通过映射表找到基地址0x2ab所对应的物理地址为0x6ab00000,然后加上偏移量45678,就可以得到实际的物理地址为:0x6ab45678;
| 0x20000000 | 0x60000000 |
| 0x20100000 | 0x60100000 |
| .... | ... |
| 0x2ab00000 | 0x6ab00000 |
因为我们在存映射表的时候就会有一个地址,所以我们可以将映射表的地址利用起来:假设映射表的地址为0x50000000,因此我们可以这样存:
| 0x6ab00000 |
| .......... |
| 0x60100000 |
| 0x60000000 |
——>0x50000000 +(2ab * 4)
.......
——>0x500000000 +(201 * 4)
——>0x500000000 +(200 * 4)
0x50000000//映射表的地址,这样我们映射表存的地址就只有物理地址了,整个表的大小就只有16k了;
下面我们通过代码实现整个过程:
我们在物理地址0x6ab45678存个数据0x12345678,要是通过虚拟地址0x2ab45678也能访问得到;就说明映射成功,否则映射失败
/*将虚拟地址0x2ab12345映射到物理地址0x6ab12345*/
int (*printf)(char *, ...) = 0xc3e114d8;
void enable_mmu();
void init_table(unsigned long *addr); int main()
{
//0x2ab00000 -> 0x6ab00000
unsigned long *virt = 0x2ab45678;
unsigned long *phys = 0x6ab45678;
*phys =0x12345678;
printf("phys %x\n", *phys);
enable_mmu();
printf("virt %x\n", *virt); return ;
} void enable_mmu()
{
/*构建表*/
unsigned long addr = 0x50000000;
init_table(addr);
/*打开mmu*/
unsigned long mmu = ;
mmu = | ( << ) | ( << ) | ( << );
__asm__ __volatile__ (
"mov r0, #3\n"
"MCR p15, 0, r0, c3, c0, 0\n"//设置为管理员
"MCR p15, 0, %0, c2, c0, 0\n"//设置表的地址
"MCR p15, 0, %1, c1, c0, 0\n"//开启mmu
:
: "r" (addr), "r" (mmu)
:
); } void init_table(unsigned long *addr)
{
unsigned long va = ;
unsigned long phys = ; //0x20000000 -> 0x60000000
//0x2ab00000 -> 0x6ab00000
for(va = 0x20000000; va < 0x30000000; va += 0x100000) {
phys = va + 0x40000000;
addr[va >> ] = phys | ;
}
//0x40000000-0x80000000 -> 0x40000000-0x80000000
for(va = 0x40000000; va < 0x80000000; va += 0x100000) {
phys = va;
addr[va >> ] = phys | ;
} //0x10000000-0x14000000 -> 0x10000000-0x140000000
for(va = 0x10000000; va < 0x14000000; va += 0x100000) {
phys = va;
addr[va >> ] = phys | ;
} }
在开发板运行结果如下:

Tiny4412MMU内存管理的更多相关文章
- .NET基础拾遗(1)类型语法基础和内存管理基础
Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开发基 ...
- PHP扩展-生命周期和内存管理
1. PHP源码结构 PHP的内核子系统有两个,ZE(Zend Engine)和PHP Core.ZE负责将PHP脚本解析成机器码(也成为token符)后,在进程空间执行这些机器码:ZE还负责内存管理 ...
- linux2.6 内存管理——逻辑地址转换为线性地址(逻辑地址、线性地址、物理地址、虚拟地址)
Linux系统中的物理存储空间和虚拟存储空间的地址范围分别都是从0x00000000到0xFFFFFFFF,共4GB,但物理存储空间与虚拟存储空间布局完全不同.Linux运行在虚拟存储空间,并负责把系 ...
- linux2.6 内存管理——概述
在紧接着相当长的篇幅中,都是围绕着Linux如何管理内存进行阐述,在内核中分配内存并不是一件非常容易的事情,因为在此过程中必须遵从内核特定的状态约束.linux内存管理建立在基本的分页机制基础上,在l ...
- Objective-C内存管理之引用计数
初学者在学习Objective-c的时候,很容易在内存管理这一部分陷入混乱状态,很大一部分原因是没有弄清楚引用计数的原理,搞不明白对象的引用数量,这样就当然无法彻底释放对象的内存了,苹果官方文档在内存 ...
- Quartz2D内存管理
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "PingFang SC"; color: #239619 } p.p2 ...
- 浅谈Linux内存管理机制
经常遇到一些刚接触Linux的新手会问内存占用怎么那么多?在Linux中经常发现空闲内存很少,似乎所有的内存都被系统占用了,表面感觉是内存不够用了,其实不然.这是Linux内存管理的一个优秀特性,在这 ...
- linux内存管理
一.Linux 进程在内存中的数据结构 一个可执行程序在存储(没有调入内存)时分为代码段,数据段,未初始化数据段三部分: 1) 代码段:存放CPU执行的机器指令.通常代码区是共享的,即其它执行程 ...
- cocos2d-x内存管理
Cocos2d-x内存管理 老师让我给班上同学讲讲cocos2d-x的内存管理,时间也不多,于是看了看源码,写了个提纲和大概思想 一. 为什么需要内存管理 1. new和delete 2. 堆上申 ...
随机推荐
- 双向链表设计与API实现
为什么需要双向链表? 单链表的结点都只有一个指向下一个结点的指针 单链表的数据元素无法直接访问其前驱元素 逆序访问单链表中的元素是极其耗时的操作! 双向链表的定义 在单链表的结点中增加一个指向其前驱的 ...
- 【资源分享】云计算 CRM 等网上搜集资料
持续更新,作为抛砖引玉,如果您有更好.更新的资源,望大家分享.共同学习.详细信息尽在 华夏编程社区(HackProLabs)-------------------------------------- ...
- Java进阶(十二)JDK版本错误之Unsupported major.minor version 51.0(jdk版本错误)
错误:Unsupported major.minor version 51.0(jdk版本错误) 如果在win7下开发项目是使用的jdk版本和项目运行服务器jdk版本不同就会出现上面的问题. 用jdk ...
- linux 网络不通问题排查
基本的排错步骤(从上往下)ping 127.0.0.1ping的通说明tcp协议栈没有问题ping 主机地址 ping的通说明网卡没有问题ping 路由器默认网关 ping的通说明包可以到达路由器最后 ...
- Redis服务信息
想要获得下面的redis服务器信息,只需要在命令行中输入:info server 部分记录了 Redis 服务器的信息,它包含以下域: redis_version : Redis 服务器版本 redi ...
- OpenCV问题集锦,图片显示不出来,WaitKey(0),imread()不能读图片,未经处理的异常,等问题集合
昨天根据uc伯克利的人工图像分割文件.seg,显示图像的时候调用了OpenCV的库函数,图片都能用imwrite写好,但是imshow死活显示不出来. 今天早上发现原来是imshow()后面应该加上: ...
- Linux文件系统及常用命令
Linux文件系统介绍: 一 .Linux文件结构 文件结构是文件存放在磁盘等存贮设备上的组织方法.主要体现在对文件和目录的组织上.目录提供了管理文件的一个方便而有效的途径. Linux使用树状目录结 ...
- EventQueue.invokeLater(new Runnable())
public class EventQueueextends ObjectEventQueue 是一个与平台无关的类,它将来自于底层同位体类和受信任的应用程序类的事件列入队列. 它封装了异步事件指派机 ...
- C# /VB.NET 插入、修改、删除Word批注
批注内容可以是对某段文字或内容的注释,也可以是对文段中心思想的概括提要,或者是对文章内容的评判.疑问,以及在阅读时给自己或他人起到提示作用.本篇文章中将介绍如何在C#中操作Word批注,主要包含以下要 ...
- CRM客户关系管理系统(十)
第十章.kingadmin+admin+actions功能开发 10.1. django admin的action 可以自己写个函数执行批量操作 crm/admin.py 后台admin actio ...