ARM中MMU地址转换理解
首先,我们要分清ARM CPU上的三个地址:虚拟地址(VA,Virtual Address)、变换后的虚拟地址(MVA,Modified Virtual Address)、物理地址(PA,Physical Address)
启动MMU后,CPU核对外发出虚拟地址VA,VA被转换为MVA供MMU使用,在这里MVA被转换为PA;最后通过PA读写实际设备
MMU的作用就是负责虚拟地址(virtual address)转化成物理地址(physical address)。 32位的CPU的虚拟地址空间达到4GB,在一级页表中使用4096个描述符来表示这4GB的空间,每个描述符代表1M的虚拟地址,要么存储了它的对应物理地址的起始地址,要么存储了下一级页表的地址。使用MVA[31:20]来索引一级页表(4096个描述符)(因为全用MVA的高12位来索引,因此大小为 2^12 = 4096)
由协处理器CP15中的寄存器C2(高18位,即[31:14]为转换表基地址,低14位为0)为一级转换表基地址,指向2^14=16KB整除的存储器即16K对齐,这个存储区称为一级转换表;MVA的高12位,即位[31:20]作为一级转换表的地址索引,因此一级转换表具有2^12=4096项,每一项的地址为32位,最高的18位[31:14]为寄存器C2的高18位,中间12位为MVA的高12位[31:20],最低2位为0b00。每一项的内容称为一个描述符,在段(Section)下,一级描述符的高12位为大小为1MB的段基地址,段内地址(偏移地址)为MVA的低20位,即段内每个存储器的地址是这样组成:高12位为一级描述符的高12位,低20位MVA的低20位。这样,借助于寄存器C2和一级描述符,将一个MVA转换成一个PA。(在这里一定要注意:MVA的高12位是用来索引4096个项的,然后使用项的内容(即描述符)的高12位为段的高12位,类似于指针里面存放地址,4096项类似指针,描述符类似指针里面的内容)
虚拟地址(注意:是一个确定的地址,不是一个空间)被MMU分成2个部分,第一部分是4096页号索引(descriptor index)即用选择4096(2^12)个号中的某个页号,比喻description index为768,页号768中保存的是物理地址的某个页框的起始地址(0x300),第二部分则是相对于section base(0x300)为起始地址空间为1M的偏移量(offset)(如下图)例如: 假设现在执行指令MOV REG, 0x30100013,虚拟地址的二进制码为00110000 00010000 00000000 00010011,前12位是Descriptor Index = 2^9+2^8+1 = 769,找到769项对应的内容0x301,偏移量为0000 00000000 00010011=13,那么段地址为0x3000000D。
5.地址转换的总体流程:
第一阶段:
(1)从虚拟地址取出前面的31-20位,作为索引。
(2)根据索引在translation table(一级页表)中找到相应的表项。
(3)根据表项最低两位的值决定第二阶段的转换方式。
00:转换无效
01:粗页转换
10:段转换
11:细页转换
(4)linux系统一般用细页转换,也有一定的处理器和操作系统用段转换,很少用粗页转换。。
6.关于TTB(translation table base)
(1)translation table存放在内存中。
(2)由程序员制造,故程序员知道其基地址(TTB)。
(3)程序员将TTB写入cp15的c2寄存器(TTB寄存器)。
(4)MMU工作的时候从c2寄存器去到TTB,从而找到translation table,进而利用虚拟地址的31-20位可以在该表中找到相应的表项,开始虚拟地址到物理地址的转换。。
范例代码:
#define GPKCON (volatile unsigned long*)0xA0008820
#define GPKDAT (volatile unsigned long*)0xA0008824 /*
* 用于段描述符的一些宏定义
*/
#define MMU_FULL_ACCESS (3 << 10) /* 段的访问权限 AP*/
#define MMU_DOMAIN (0 << 5) /* 属于哪个域 */
#define MMU_SPECIAL (1 << 4) /* 必须是1 */
#define MMU_CACHEABLE (1 << 3) /* cacheable 快速访问*/
#define MMU_BUFFERABLE (1 << 2) /* bufferable 缓冲区 */
#define MMU_SECTION (2) /* 表示这是段描述符 */
#define MMU_SECDESC (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | MMU_SECTION)
#define MMU_SECDESC_WB (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | MMU_CACHEABLE | MMU_BUFFERABLE | MMU_SECTION) void create_page_table(void)
/*
1. 建立页表
2. 写入TTB (cp15 c2)
3. 使能MMU
*/
{
unsigned long *ttb = (unsigned long *)0x50000000;
unsigned long vaddr, paddr; vaddr = 0xA0000000;
paddr = 0x7f000000;
*(ttb + (vaddr >> )) = (paddr & 0xFFF00000) | MMU_SECDESC; vaddr = 0x50000000; /* 映射内存 */
paddr = 0x50000000;
while (vaddr < 0x54000000)
{
*(ttb + (vaddr >> )) = (paddr & 0xFFF00000) | MMU_SECDESC_WB;
vaddr += 0x100000; /* 每一个表项只能映射1M */
paddr += 0x100000;
} } void mmu_init()
{
__asm__( /*设置TTB 写入cp15的c2中*/
"ldr r0, =0x50000000\n"
"mcr p15, 0, r0, c2, c0, 0\n" /*不进行权限检查 域的访问权限取决于cp15的c3寄存器*/
"mvn r0, #0\n"
"mcr p15, 0, r0, c3, c0, 0\n" /*使能MMU*/
"mrc p15, 0, r0, c1, c0, 0\n"
"orr r0, r0, #0x0001\n"
"mcr p15, 0, r0, c1, c0, 0\n"
:
:
);
} int gboot_main()
{
create_page_table();
mmu_init(); *(GPKCON) = 0x1111;
*(GPKDAT) = 0xe; return ;
}
ARM中MMU地址转换理解的更多相关文章
- 对MMU段式转换的理解
本文将详细介绍MMU段式转换的过程,并在文末附上一篇讲MMU比较详细的文章.具体什么是MMU,什么时段是转换就不在本文讲了,直接戳文末的链接. 首先,进行段式转换的条件.我们要拥有一个虚拟地址,还有一 ...
- PHP中IP地址与整型数字互相转换详解
这篇文章主要介绍了PHP中IP地址与整型数字互相转换详解,本文介绍了使用PHP函数ip2long与long2ip的使用,以及它们的BUG介绍,最后给出自己写的两个算法,需要的朋友可以参考下 IP转换成 ...
- 网络编程中常见地址结构与转换(IPv4/IPv6)
1. sockaddr/sockaddr_in/in_addr (IPv4).sockaddr6_in/in6_addr/addrinfo (IPv6) struct sockaddr { unsig ...
- 用crash tool观察ARM64 Linux地址转换
初学者学习Linux系统地址转换时,如果只是学习理论,又或者研读代码,那可能感觉比较枯燥.此时如果可以利用某些工具实际观察一下地址转换的过程,那可能会给枯燥的内核学习带来些微的乐趣.crash too ...
- 对Java中字符串的进一步理解
字符串在程序开发中无处不在,也是用户交互所涉及到最频繁的数据类型,那么字符串不仅仅就是我们简单的理解的String str = "abc";一起来更加深入的看一下 在Java中,字 ...
- NAT地址转换原理全攻略
NAT转换方式及原理 在NAT的应用中,可以仅需要转换内部地址(就是“内部本地址”转换成“内部全局地址”),这是最典型的应用,如内部网络用户通过NAT转换共享上网:也可以是仅需要转换外部地址(就是“外 ...
- X86在逻辑地址、线性地址、理解虚拟地址和物理地址
参考:http://bbs.chinaunix.net/thread-2083672-1-1.html 本贴涉及的硬件平台是X86.假设是其他平台,不保证能一一对号入座.可是举一反三,我想是全然可行的 ...
- UNIX网络编程——socket概述和字节序、地址转换函数
一.什么是socket socket可以看成是用户进程与内核网络协议栈的编程接口.socket不仅可以用于本机的进程间通信,还可以用于网络上不同主机的进程间通信. socket API是一层抽象的网络 ...
- 【C++】类中this指针的理解
转自 苦涩的茶https://www.cnblogs.com/liushui-sky/p/5802981.html C++类中this指针的理解 先要理解class的意思.class应该理解为一种类型 ...
随机推荐
- 长期内部推荐SAP职位,包括Java ABAP 咨询顾问,Developer,架构师等。
长期内部推荐SAP职位,包括Java ABAP 咨询顾问,Developer,架构师等. 有需要请发简历到邮箱 LoB Position LocationAcquisitions Hybris ...
- C# 枚举显示中文
转自:http://www.cnblogs.com/yank/archive/2011/09/08/EnumDisplayInChinese.html using System; using Sy ...
- js时间冒泡,阻止事件冒泡
首先解释一下事件冒泡神什么, 在js中,假如在div中嵌套一个div 如 <style type="text/css"> #box1{width:500px;heigh ...
- Java构造和解析Json数据的两种方法详解一
一.介绍 JSON-lib包是一个beans,collections,maps,java arrays 和XML和JSON互相转换的包,主要就是用来解析Json数据,在其官网http://www.js ...
- 洛谷P1518 两只塔姆沃斯牛 The Tamworth Two
P1518 两只塔姆沃斯牛 The Tamworth Two 109通过 184提交 题目提供者该用户不存在 标签USACO 难度普及+/提高 提交 讨论 题解 最新讨论 求数据 题目背景 题目描 ...
- c++11 中的 move 与 forward
[update: 关于左值右值的另一点总结,请参看这篇] 一. move 关于 lvaue 和 rvalue,在 c++11 以前存在一个有趣的现象:T& 指向 lvalue (左传引用), ...
- TCP/IP详解学习笔记(1)-- 概述
1.TCP/IP的分层结构 网络协议通常分不同层次进行开发,每一层分别负责不同的同信功能.TCP/IP通常被认为是一个四层协议系统. 如图所示. 1)链路层(数据链路层 ...
- Vim与GCC和gdb完美组合
一.vim vim修改一下配置文件后,如果你稍微会点vim的命令使用,那可比一般的编辑器好用啊,如果一点不会vim的命令使用,就跟一般编辑器一样使用. 打开etc/vim/vimrc文件 这里的引号是 ...
- 把jqmobi 變成jQuery 的插件 從此使用jQuery
因為項目的要求,需要用到jQuery 的一些插件 ,而我又是用jqmobi的....o(╯□╰)o 看看文檔.....把jqmobi 變成jQuery的插件 問題就解決了 O(∩_∩)O哈哈~ 官 ...
- jsp页面el表达式不起作用
web.xml中2.4版本的默认导入的standerd.jar,和jstl.jar是使用el表达式的包是启动的而2.5版本的web.xml中默认是关闭的所以在2.5的所有jsp中需要启动一下用< ...