第三十五天:Tiny4412驱动开发之配置MMU

    MMU表示内存管理单元,负责虚拟内存映射到物理内存。

   虚拟地址映射到物理地址的关键是构建映射表。MMU就是利用映射表格将虚拟地址转换成物理地址。虚拟地址在32系统中为4G,地址占4字节,如果映射表格中虚拟地址和物理地址是一一对应的关系,一条记录就占8字节,那么映射表就要32G.这明显是不合理的。

   于是通过二级映射解决这个问题。地址共32位,把前12位作为基地址,后20位作为偏移量,将虚拟地址和物理地址作为的前12位一一对应,12位就是2的12次方为4k。 一条记录8字节,那么映射表格就只有32k,
  下图左边为虚拟地址,右边为物理地址。比如有个虚拟地址为0x00123456,基地址为001 偏移量为23456.先通过映射表找到对于的物理地址为0x60100000,然后加上偏移量就是实际的地址0x60123456。

0x00100000 0x60100000
0x00200000 0x60200000
0x00300000 0x60300000
0x00400000 0x60400000

在tiny4412中,内存映射表更加的简单。把因为表格也是存放在内存中的,内存也有地址。那么就把内存利用起来。看下图:

  

 0x70000000就表示映射表存储的位置,映射表格的内容就只有物理地址。虚拟地址就在表格的地址中体现。这样的话,内存映射表又缩减了一半,4G的虚拟地址只要16k的表格就能全部映射。

  先看Tiny4412的内存表:

从表中可以知道0x30000000地址是没有内容的。现在要开启MMU,将0x30000000内存映射到0x50000000地址去,如果能够访问到0x3000000,就表示映射成功。代码如下:

 1 int (*printf)(char *, ...) = 0xc3e114d8;
 2
 3 void init_ttb(unsigned long *ttb);
 4
 5 int main()
 6 {
 7     //0x32300000 -> 0x52300000;
 8     unsigned long *pp = 0x52300000;
 9     *pp = 0x22222222;
10     printf("*pp is %x\n", *pp);
11     //step 1: set mmu table
12     unsigned long ttb = 0x70000000;
13     init_ttb(ttb);
14     //step 2: enable mmu table
15     unsigned long mmu = 0;
16     mmu = 1 | (1 << 3) | (1 << 8);
17     __asm__ __volatile__(//开启mmu必须用汇编实现
18         "mov r0, #3\n"
19         "mcr p15, 0, r0, c3, c0, 0\n" //manager
20         "mcr p15, 0, %0, c2, c0, 0\n" //ttb address
21         "mcr p15, 0, %1, c1, c0, 0\n" //enable mmu
22         :
23         : "r" (ttb), "r" (mmu)
24     );
25
26     unsigned long *pv = 0x32300000;
27     printf("*pv is %x\n", *pv);
28 }
29
30 void init_ttb(unsigned long *ttb)
31 {
32     unsigned long va = 0;
33     unsigned long pa = 0;
34     //0x00000000 ~0x14000000  -> 0x00000000 ~0x14000000
35     for(va=0x00000000; va<0x14000000; va+=0x100000){
36         pa = va;
37         ttb[va >> 20] = pa | 2;
38     }
39
40     //0x40000000 ~0x80000000  -> 0x40000000 ~0x80000000
41     for(va=0x40000000; va<0x80000000; va+=0x100000){
42         pa = va;
43         ttb[va >> 20] = pa | 2;
44     }
45     //0x30000000 ~0x40000000  -> 0x50000000 ~0x60000000
46     for(va=0x30000000; va<0x40000000; va+=0x100000){
47         pa = va + 0x20000000;
48         ttb[va >> 20] = pa | 2;
49     }
50 }

  

  可以访问0x32300000的内容,说明MMU开启成功。

  下面是关于汇编代码中开启MMU的介绍。先是在ARM开发手册中查找关于MMU控制的相关信息,下图是MMU配置的内容

上面代码16行就是MMU的配置,将第一位置1表示 开启MMU,第三位置一表示开启写缓存。

未完待续。。。(等水平提升了在继续写,剩下的汇编代码实在看不懂)

时间: 2024-10-20 08:14:57

第三十五天:Tiny4412驱动开发之配置MMU的相关文章

第三十七天:Tiny4412驱动开发之二级跳转

ARM五级流水线:取值,译码,执行,访存,回写.未定义指令异常和SWI软中断发生在译码阶段,其它异常发生在执行阶段. 现在假设有五条指令,三指令正在执行的时候,四指令在译码过程中发生未定义指令异常,跳转到异常处理程序回来后,因为 PC指向五指令,所以继续执行五指令的内容. 但是,如果程序在三指令执行期间发生错误,处理回来后到达五指令,把四指令跳过了.解决方式是在处理的把PC的值减去四,具体的代码会在后面的中断代码中体现. 前文的最后提到如果三个异常同时发生,三个异常处理程序员都要放到指定的地址中

Linux学习总结(三十五)lamp之访问日志配置

一 访问日志不记录静态文件访问信息 网站大多元素为静态文件,如图片.css.js等,记录这些访问信息对我们运维工作没有多大意义,如果一个站点访问量很大,那么一天就可以达到几GB.影响我们磁盘的工作效率,那么我们就可以配置虚拟主机限制记录这些信息.把虚拟主机配置文件改成如下: <VirtualHost *:80> DocumentRoot "/data/wwwroot/www.123.com" ServerName www.123.com ServerAlias 123.co

QT开发(三十五)——QT进程间通信

QT开发(三十五)--QT进程间通信 Qt 是一个跨平台的应用框架,其进程间通信机制当然可以使用所在平台的进程间通信机制,如在Windows平台上的Message机制.共享内存.文件映射.管道.Socket等.其中,Qt对一些许多平台共有的IPC机制进行了封装. 一.TCP/IP 其实就是通过网络模块实现的IPC.不过Qt对其进行了封装,并提供了两个层次的API,包括应用程序级的QNetworkAccessManager, QFtp等和底层的QTcpSocket, QTcpServer, QSs

Python进阶(三十五)-Fiddler命令行和HTTP断点调试

Python进阶(三十五)-Fiddler命令行和HTTP断点调试 一. Fiddler内置命令 ??上一节(使用Fiddler进行抓包分析)中,介绍到,在web session(与我们通常所说的session不是同一个概念,这里的每条HTTP请求都称为一个session).界面中能够看到Fiddler抓取的全部HTTP请求.而为了更加方便的管理全部的session, Fiddler提供了一系列内置的函数用于筛选和操作这些session(习惯命令行操作Linux的童鞋应该能够感受到这会有多么方便

NeHe OpenGL教程 第三十五课:播放AVI

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第三十五课:播放AVI 在OpenGL中播放AVI: 在OpenGL中如何播放AVI呢?利用Windows的API把每一帧作为纹理绑定到OpenGL中,虽然很慢,但它的效果不错.你可以试试. 首先我得说我非常喜欢这一章节.Jonat

IT行业:听说编程编到三十五岁就没人要了一定要转行找出路

我听说编程编到三十五岁就没人要了一定要转行找出路是吗? 这个观点虽然很流行,但根本不值一驳.现在三十五岁转行的那些人,都具有前面所说的那些特征,对学习新技术不感兴趣,对探索计算机的本质不感兴趣,得过且过,下了班就是打游戏.看电视,总之就是懒.如果是开出租.摆摊,勤快人懒人都有饭吃,而IT这一行对懒人是非常无情的,懒人就不该入IT这一行,不从自身找原因,却到处散布这种言论,怪社会不好,打击新人的信心,着实可恨. 另外一种情况,编程编到三十五岁,进入公司的管理层,或者自己创业,这都是很勤快的人,如果

“全栈2019”Java多线程第三十五章:如何获取线程被等待的时间?

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多线程第三十五章:如何获取线程被等待的时间? 下一章 "全栈2019"Java多线程第三十六章:如何设置线程的等待截止时间 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复&qu

中国,第三十五个生日.周以纯

1 群山对江河说 江河对森林说 森林对土地和太阳说 土地和太阳对人说 十亿中华儿女对世界说—— 中国!中国 沿着历史长河的古道 走进第三十五个 金灿灿的十月 大地和天空 欢声和金风,旗的红云 神圣的五颗金星 镶嵌在中国的 平川.高原.大漠…… 从未有过的蓬勃—— 风,撒着欢儿奔跑 雨,适着时令洒落 心,在一个节拍上跳荡 爱,在一棵大树上结果 2 呵!中国 在过第三十五个生日 心地,再不窄小狭隘 却是宇宙般寥阔 胸怀,再无骤雨恶风 却是蓝天般澄澈 眼界,再不短浅局限 却是穿越一切微观宏观世界 该摈

Welcome to Swift (苹果官方Swift文档初译与注解三十五)---248~253页(第五章-- 函数 完)

Function Types as Return Types (函数类型作为返回值类型) 一个函数的类型可以作为另一个函数的返回值类型.可以在一个函数的返回值箭头后面写上一个完整的函数类型. 例如: 下面的例子定义了两个简单的函数,分别为stepForward 和 stepBackward.其中stepForward函数返回值比它的输入值多1,stepBackward函数返回值比它输入值少1.这两个函数的 类型都是(Int) -> Int: func stepForward(input: Int