浅析线性地址到物理地址的转换

. 概念介绍:

1.线性地址(linear address)(也称虚拟地址virtual address):是一个32位无符号整数,用来表示高达4GB的地址。

2.物理地址(physical address):实际地址。

3.VM 即虚拟内存 ,PM 即物理内存

4.(1)PGD(Page Global Directory) 即页全局目录。

(2)PUD(Page Upper Directory)即页上级目录。

(3)PMD(Page Middle Directory)即页中间目录。

(4)PT即页面表, PT中的表项称为PTE, 是“Page Table Entry”的缩写。

5.offset 即位移量,偏移量。

二. 模型分析:

Linux从2.6.11开始采用四级分页模型:(为了适用于32位和64位系统),linux目前采用的也是四级分页机制,所以我的讨论也基于此。

1. 线性地址

不管系统采用多少级分页模型,线性地址本质上都是索引+偏移量的形式,甚至你可以将整个线性地址看作N+1个索引的组合,N是系统采用的分页级数。在四级分页模型下,线性地址被分为5部分,如下图1:

图1

在线性地址中,每个页表索引即代表线性地址在对应级别的页表中中关联的页表项。正是这种索引与页表项的对应关系形成了整个页表映射机制。

2. 页表

多个页表项的集合则为页表,一个页表内的所有页表项是连续存放的。页表本质上是一堆数据,因此也是以页为单位存放在主存中的。因此,在虚拟地址转化物理物理地址的过程中,每访问一级页表就会访问一次内存。

3. 页表项

从四种页表项的数据结构可以看出,每个页表项其实就是一个无符号长整型数据。每个页表项分两大类信息:页框基地址和页的属性信息。在x86-32体系结构中,每个页表项的结构图2如下:

                                 图2

这个图是一个通用模型,其中页表项的前20位是物理页的基地址。由于32位的系统采用4kb大小的 页,因此每个页表项的后12位均为0。内核将后12位充分利用,每个位都表示对应虚拟页的相关属性。

不管是哪一级的页表,它的功能就是建立虚拟地址和物理地址之间的映射关系,一个页和一个页框之间的映射关系体现在页表项中。

上图中的物理页基地址是 个抽象的说明,如果当前的页表项位于页全局目录中,这个物理页基址是指页上级目录所在物理页的基地址;如果当前页表项位于页表中,这个物理页基地址是指最 终要访问数据所在物理页的基地址。

. 转换机制介绍:

如下图3所示,线性地址到物理地址的转换机制结构图:

                                  图3

基本过程如下:

1.从CR3寄存器中读取页目录所在物理页面的基址(即所谓的页目录基址),从线性地址的第一部分获取页目录项的索引,两者相加得到页目录项的物理地址。

2.第一次读取内存得到pgd_t结构的目录项,从中取出物理页基址取出(具体位数与平台相关,如果是32系统,则为20位),即页上级页目录的物理基地址。

3.从线性地址的第二部分中取出页上级目录项的索引,与页上级目录基地址相加得到页上级目录项的物理地址。

4.第二次读取内存得到pud_t结构的目录项,从中取出页中间目录的物理基地址。

5.从线性地址的第三部分中取出页中间目录项的索引,与页中间目录基址相加得到页中间目录项的物理地址。

6.第三次读取内存得到pmd_t结构的目录项,从中取出页表的物理基地址。

7.从线性地址的第四部分中取出页表项的索引,与页表基址相加得到页表项的物理地址。

8.第四次读取内存得到pte_t结构的目录项,从中取出物理页的基地址。

9.从线性地址的第五部分中取出物理页内偏移量,与物理页基址相加得到最终的物理地址。

10.第五次读取内存得到最终要访问的数据。

整个过程是比较机械的,每次转换先获取物理页基地址,再从线性地址中获取索引,合成物理地址后再访问内存。不管是页表还是要访问的数据都是以页为单 位存放在主存中的,因此每次访问内存时都要先获得基址,再通过索引(或偏移)在页内访问数据,因此可以将线性地址看作是若干个索引的集合。

举例分析:

 

某任务加载后,在4GB虚拟地址空间创建了一个段,起始地址为0x00800000, 段界限为0x5000,字节粒度。当前任务执行时,段寄存器DS指向该段。又假设执行了下面一条指令: mov edx, [0x1050],问此时对应的物理地址是多少?

答:此时,段部件会输出线性地址0x00801050。在没有开启分页机制时, 这就是要访问的物理地址。但现在开启了分页机制,所以这是一个下虚拟地址,要经过页部件转换,才能得到物理地址。

如下图4所示,处理器的页部件专门负责线性地址到物理地址的转换工作。它首先将段部件送来的32位线性地址分为3段,分别是高10位,中间10位,低12位。高10位是页目录的索引,中间10位是页表的索引,低12位则作为页内偏移量来用。

                           图4

当前任务页目录的物理地址在处理器的CR3寄存器中,假设它的内容为0x00005000 。段管理部件输出的线性地址是0x00801050 。其二进制的形式如图中给出。高10位是十六进制的0x002。它是页目录表内的索引,处理器将它乘以4(因为每个目录项4字节)。作为偏移量访问页目录。最终处理器从物理地址00005008处取得页表的物理地址0x08001000。

线性地址的中间10位为0x001,处理器用它作为页表索引取得页的物理地址。将该值乘以4,作为偏移量访问页表。最终,处理器又从物理地址08001004处取得页的物理地址,这就是我们一直努力寻找的那个页。

页的物理地址是0x0000C000,而线性地址的低12位是数据所在的页内偏移量,故处理器将它们相加,得到物理地址0x0000C050,这就是线性地址0x00801050所对应的物理地址,要访问的数据就在这里。

当任务加载时,操作系统先创建虚拟的段,并根据段地址的高20位决定它要用到哪些页目录项和页表项。然后,寻找空闲的页,将原本应该写入段中的数据写到一个或者多个页中,并将页的物理地址填写到相对应的页表项中。只有这样做了,当程序运行的时候,才能以相反的顺序进行地址变换,并找到正确的数据。

. 为什么采用分页机制:

其实它的主要目的在于实现虚拟存储器。分页是通过内存控制单元(MMU)进行的。分页使得线性地址转换为物理地址。在分页中,为了效率起见,将线性地址分成固定长度,称为页,与页长度一致的是页框(物理页)。每个页框包含一个页。把线性地址映射到物理地址的数据结构称为页表。页表存放在主存之中,并在启用分页之前由内核对其进行初始化。

另外,因为分页机制的存在,程序使用的都是线性地址空间,而不再直接是物理地址。这好像是操作系统位应用程序提供了一个不依赖于硬件(物理内存)的平台,应用程序不必关心实际上有多少物理内存,也不必关心正在使用的是哪一段内存,甚至不必关心某一个地址是在物理内存里面还是在硬盘中。只要像操作系统申请就行,而操作系统全权负责了这其中的转换工作。

时间: 2024-12-28 02:19:04

浅析线性地址到物理地址的转换的相关文章

操作系统 内存地址(逻辑地址、线性地址、物理地址)概念

逻辑地址(Logical Address) 是指由程序产生的与段相关的偏移地址部分.例如,你在进行C语言指针编程中,可以读取指针变量本身值(&操作),实际上这个值就是逻辑地址,它是相对于你当前进程数据段的地址,不和绝对物理地址相干.只有在Intel实模式下,逻辑地址才和物理地址相等(因为实模式没有分段或分页机制,Cpu不进行自动地址转换):逻辑也就是在Intel 保护模式下程序执行代码段限长内的偏移地址(假定代码段.数据段如果完全一样).应用程序员仅需与逻辑地址打交道,而分段和分页机制对您来说是

逻辑地址、线性地址、物理地址以及虚拟存储器

http://blog.csdn.net/mrbuffoon/article/details/48947267 Note:本文是基于80×86微处理器进行原理总结. 在内存地址上,我们要区分逻辑地址.线性地址以及物理地址这三个概念.逻辑地址:包含在机器语言指令中用来指定一个操作数或者一条指令的地址.每一个逻辑地址都由一个段选择符和段偏移量组成.线性地址:也称为虚拟地址,也不是一个真实的地址,他是对应了硬件页式内存转换前地址.物理地址:就是物理内存中的真正地址. 内存控制单元(MMU)通过分段单元

linux内存管理---虚拟地址、逻辑地址、线性地址、物理地址的区别(一)

分析linux内存管理机制,离不了上述几个概念,在介绍上述几个概念之前,先从<深入理解linux内核>这本书中摘抄几段关于上述名词的解释: 一.<深入理解linux内核>的解释 逻辑地址(Logical Address) 包含在机器语言指令中用来指定一个操作数或一条指令的地址(有点深奥).这种寻址方式在80x86著名的分段结构中表现得尤为具体,它促使windows程序员把程序分成若干段.每个逻辑地址都由一个段和偏移量组成,偏移量指明了从段开始的地方到实际地址之间的距离. 线性地址(

[转帖]Linux下逻辑地址、线性地址、物理地址详细总结

Linux下逻辑地址.线性地址.物理地址详细总结 https://www.cnblogs.com/alantu2018/p/9002441.html 总结的挺好的 现在应该是段页式管理 使用MMU和TLB 实现 线性地址 逻辑地址 和物理地址的映射. 一.逻辑地址转线性地址    机器语言指令中出现的内存地址,都是逻辑地址,需要转换成线性地址,再经过MMU(CPU中的内存管理单元)转换成物理地址才能够被访问到. 我们写个最简单的hello world程序,用gcc编译,再反编译后会看到以下指令:

linux2.6 内存管理——逻辑地址转换为线性地址(逻辑地址、线性地址、物理地址、虚拟地址)

Linux系统中的物理存储空间和虚拟存储空间的地址范围分别都是从0x00000000到0xFFFFFFFF,共4GB,但物理存储空间与虚拟存储空间布局完全不同.Linux运行在虚拟存储空间,并负责把系统中实际存在的远小于4GB的物理内存根据不同需求映射到整个4GB的虚拟存储空间中.Linux主要工作在保护模式下.80X86从逻辑地址到物理地址变换中经过了两个阶段.第一阶段使用分段机制把程序的逻辑地址变换成处理器可寻址内存空间(称为线性地址空间)中的地址.第二阶段的分页机制把线性地址转换成物理地址

逻辑地址、线性地址和物理地址的关系

http://blog.csdn.net/prike/article/details/52722934 物理内存:数据寻址用:mmu联系: 虚拟地址:cpu传给mmu的:给程序员使用: 逻辑地址:cpu指令使用:符合可执行文件的格式. 二.物理地址.虚拟地址(线性地址).逻辑地址 任何时候,计算机上都存在一个程序能够产生的地址集合,我们称之为地址范围.这个范围的大小由CPU的位数决定,例如一个32位的CPU,它的地址范围是0~0xFFFFFFFF (4G),而对于一个64位的CPU,它的地址范围

LINUX 逻辑地址、线性地址、物理地址和虚拟地址 转

一.概念物理地址(physical address)用于内存芯片级的单元寻址,与处理器和CPU连接的地址总线相对应.——这个概念应该是这几个概念中最好理解的一个,但是值得一提的是,虽然可以直接把物理地址理解成插在机器上那根内存本身,把内存看成一个从0字节一直到最大空量逐字节的编号的大数组,然后把这个数组叫做物理地址,但是事实上,这只是一个硬件提供给软件的抽像,内存的寻址方式并不是这样.所以,说它是“与地址总线相对应”,是更贴切一些,不过抛开对物理内存寻址方式的考虑,直接把物理地址与物理的内存一一

Linux内存管理--虚拟地址、逻辑地址、线性地址和物理地址的区别(二)【转】

本文转载自:http://blog.csdn.net/yusiguyuan/article/details/9668363 这篇文章中介绍了四个名词的概念,下面针对四个地址的转换进行分析 CPU将一个虚拟内存空间中的地址转换为物理地址,需要进行两步(如下图): 首先,将给定一个逻辑地址(其实是段内偏移量,这个一定要理解!!!),CPU要利用其段式内存管理单元,先将为个逻辑地址转换成一个线程地址, 其次,再利用其页式内存管理单元,转换为最终物理地址. 这样做两次转换,的确是非常麻烦而且没有必要的,

线性地址到物理地址的映射

http://book.51cto.com/art/200812/103230.htm 分页机制是80x86内存管理机制的第二部分.它在分段机制的基础上完成虚拟(逻辑)地址到物理地址转换的过程.分段机制把逻辑地址转换成线性地址,而分页则把线性地址转换成物理地址.分页可以用于任何一种分段模型.处理器分页机制会把线性地址空间(段已映射到其中)划分成页面,然后这些线性地址空间页面被映射到物理地址空间的页面上.分页机制有几种页面级保护措施,可和分段机制保护机制合用或替代分段机制的保护措施.例如,在基于页