应用程序是运行在虚拟内存中的,使用的也是虚拟地址, cpu负责虚拟地址和物理地址的转换。
虚拟地址和物理地址
物理地址: 将物理内存看成一个大数组,每个字节都可以通过与之唯一对应的地址进行访问,这叫做物理地址。CPU通过总线发送访问物理地址的请求,从内存中读取数据或向其中写入数据。
虚拟地址: 应用程序通过使用虚拟地址访问存金融工程储在内存中的数据和代码,程序执行过程中,cpu通过内存管理单元(MMU)将虚拟地址转换为物理地址。
运行一条指令时,操作系统首先把程序从磁盘/SSD门萨俱乐部中加载到物理内存中,然后让CPU去执行第一条指令,指令位于内存中,CPU要读取的是虚拟地址,MMU会将虚拟地址转换为物理地址,读请求到达物理地址, 物理内存将物理地址对应的内容发送给CPU
MMU机制实现方式和原理MMU将虚拟地址转化为物理地址的方式有两种
1 分段机制:将虚拟空间分为很多段,代码段,数据段,将每段分为段号,段内地址(段内偏移) 。段表存储分段信息,包括起始地址和段长。根据段表基址寄存器找到段表的位置,然后根据段号和段内地址就可以定位最终的物理地址。虚拟地址相邻的段可以不相邻,可以实现物理内存资源的离散分配,导致内存碎片
2 分页机制
将虚拟地址分成连续的,等长的虚拟页,物理页页划分为连续等长的,也分为虚拟页号和页内偏移量。查找过程基本和 分段机制一致。分页机制按照固定页的大小分配物理内存,使得物理内存资小米路由器3源易于管理,可有效避免分段机制外部碎片的问题。
4 虚拟地址低48位参与地址翻译,页表级数为4级,虚拟页大小为4kb。物理内存被划分为连续4kb大小的物理页,
一个64位在逻辑上被分成如下几个部分:
63-48位:全百度问题为0或全是1,通常操作系统选择是:应用程序使用的虚拟地址这些位都是0,虚拟空间大小可以达到2 的48个字节
47-39 位:这9位作为虚拟地址在第0级页表中的索引值
38-30位: 这9位作为虚拟地址在第1级页表中的索引值
29-21位: 这9位作为虚拟地址在第2级页表中的索引值
20-12位:这9位作为虚拟地址在第3级页表中的索引值
11-0位:由于页的大小是4kb,所以低12位代表页内偏移量
MMU寻址过程当MMU翻译虚拟地址,首先根据 页表基地址寄存器 中的物理地址 找到 第0级页表,然后将虚拟页号0 (第47-39位)作为页表索引,读取第0级页表项,在其中存储着下一级(第1级)页表页的物理地址,MMU按照类似方式将虚拟地址的虚拟页号1(38-30位)作为页表项,往下类推,找到第3级页表中的页表找到该虚拟地址对应的物理页号,再结合虚拟地址中的页内偏移量即可获得最终的物理地址。
TLBTLB:MMU引入转址旁路缓存来加速地址翻译的过程,缓存了虚拟页号和物理页号印射关系, 以建值对的哈希表,建是虚拟页号,值是物理页号。
命中则是TLB命中,不命中则是TLB不命中,TLB采用分层架构,分为L1和L2两层,分层如下图。每个CPU核心只有约一千条TLB缓存项,如果TLB已经满了,则根据硬件预定的策略替换。
TLB刷新:
换页机制与页替换策略换页机制:当物理内存容量不够的时候,操作系统应该把若干物理页内容写到类似磁盘这种容量更大且更加便宜的存储设备中,然后就可以回收物理页继续使用。比如应用程序A那里回收物理页P,操作系统需要将物理页p写到磁盘上的一个位置。在应用程序A中去除虚拟页V的映射,物理页P就被操作系统回收,并且分配给别的应用程序使用。此时,虚拟页v就处于已分配但是未映射至物理内存的状态。
缺页异常:应用程序访问已经分配但是未映射到物理内存的虚拟页时,就会出发却页异常。
页替换策略:
当需要的内存小于某个阀值,根据页替换策略选择一个或者一些物理页换出到物理页以获得空间。页替换策略十分耗性能,因为从硬盘换到内存十分消耗性能。
MIN策略/OPT策略:优先选择未来不会被选择的页,很难实现
FIFO关你屁事策略:先进先出策略,优先选择最先换入的页进行换出
Second Change策略:FIFO策略的改进版,为每个物理页维护一个访问标志位,
LRU策略:优先选择最久未被访问的页,维护链表,经常访问的页号位于链表的尾部,不经常访问的内存页号放置在链表头部,每次选择换出位于链表头部的页
MRU策略:优先选择最近访问的内存页,与LRU情况相反
时钟算法策略:
虚拟内存的功能:
共享内存:
写时拷贝功能共享内存允许同一个物理页在不同的应用程序间共享,可以i让不同的应用程序之间相互通信,传递数据
写时拷贝:允许应用程序A和应用程序B以只读的方式共享同一段物理内存,一旦某个应用程序对该内存区域进行修改就会出发缺页异常。由于违反权限,在触发后,cpu同样会将控制流传递给操作系统预先设置的缺页异常处理函数。在该函数中,操作系统会发现当前的缺页异常是由于应用程序写了只读内存,帕劳自由行而且相应的内存区域又是被操作系统标记成写时拷贝的,于是操作系统会在物理内存中将缺页异常对应的物理页重新拷贝一份,并且将新拷贝的物理页以可读可写的方式重新映射给触发异常的应用程序,此后再回复应用程序的执行。
应用场景:一: 两个应用程序共享内存数据,在物理页只存储一份,以只读的方式映射给两个应用程序,显著的节约物理内存资源。二:一个应用程序以fork系统调用创建子程序。
这两种场景一能够节约物理内存资源,不同的应用程序以写时拷贝的方式映射相同的动态链接库,另一方面:可以让父子进程以只读的方式共享全部的内存数据,避免写时拷贝的时候的内存消耗。
页表47-12位存储物理地址,页号,剩下的位多为属性位,虚拟页的权限是否可写,可执行。
内存去重,内存压缩,大页机制内存去重:基于写时拷贝技术,操作系统产生了KSM,会定时进行内存去重,在内存中扫描相同的物理页,找到映射的虚拟页,然后只保留一个物理页,并将其他的虚拟页以写时拷贝的技术映射到这个物理页,释放其他物理页。但是这样可能导致性能下降。
内存压缩:liunx支持zswap机制,操作系统将压缩的内存数据写入zswap区域,依旧是内存区域,将内存数据写到磁盘设备的操作可以延迟完成。
大页机制:是为了解决TLB空间,缓存不够用的问题,大页的带下可以是2MB,设置是1GB,相比于4kb大小的页,使用大页可以大幅度减少TLB的占用量,比如之前内存大小位4kb,访问2Mb的内存久需要512个tlb缓存项,现在访问2mb就只需要1个tlb,透明大页机制还可以自动将4kb的内存合并为2Mb的内存
符号说明虚拟内存地址寻址图9-12展示了MMU如何利用页表来实现这种映射。CPU中的一个控制寄存器,页表基址寄存器(Page Table Base Register,PTBR)指向当前页表。N位的虚拟地址包含两个部分:一个p位的虚拟页表偏移(Virtual Page Offset,VPO)和一个(n-p)位的虚拟页号(Virtual Page Number,VPN)。MMU利用VPN来选择适当的PTE。将页表条目中物理页号(Physical Page Number,PPN)和虚拟地址中的VPO串联起来,就得到了相应的物理地址。需要注意的是物理和虚拟页面都是p字节的,所以物理页面偏移(Physical 吊带连体裤Page Offset,PPO)和VPO是相同的。
CPU与MMU寻址过程下图展示了当页面命中时,CPU硬件执行的步骤。
第一步:处理器生成一个虚拟地址,并把它传送给MMU。第二步:MMU生成PTE地址,并从高速缓存/主存请求得到它。第三步:高速缓存/主存向MMU返回PTE。第四步:MMU构造物理地址,并把它传送给高速缓存社科院研究生院/主存。第五步:高速缓存/主存返回所请求的数据字给处理器。页面命中完全是由硬件来处理的,与之不同的是,处理缺页要求硬件和操作系统内核协作完成。过程如下图所示:
第一步到第三步和上图的过程是一样的。
第四步:PTE中的有效位是0,所以MMU触发了一次异常,传递CPU中的控制到操作系统内核中的缺页异常处理程序。第五步:缺页处理程序确定出物理内存中的牺牲页,如果这个页面已经被修改了,则把它换出到磁盘。第六步:缺页处理程序页面调入新的页面,并更新内存中的PTE。第七步:缺页处理程序返回到原来的进程,再次执行导致缺页的命令,CPU将引起缺页的虚拟地址重新发送给MMU。因为虚拟页面现在缓存在物理内存中,所以就会命中。
TLB执行过程以及作用许多系统会在MMU中包括一个关于PTE的小北京市第一中学的缓存,称为翻译后备缓冲器(Translation Lookaside Buffer,TLB。TLB是一个小的、虚拟寻址的缓存,其中每一行都保存着一个由单个PTE组成的块。TLB通常有高度的相联度。
如图所示,用于组选择和行匹配的索引和标记字段是从虚拟地址中的虚拟页号中提取出来的。如果TLB有T=个组,那么TLB索引(TLBI)是由VPN的t个最底位组成的,而TLB标记(TLBT)是由VPN中剩余的位组成的。
多级页表如果我们有一个32位的地址空间,4KB的页面和一个4字节的PTE,那么即使应用所引用的只是虚拟地址空间很小的一部分,也总是需要一个4MB的页表驻留在内存中。对于地址空间为64位的系统来说,问题将变得更复杂。
这种方法从两个方面减少了内存要求。第一,如果一级页表中的一个PTE是空的,那么对应的二级页表就根本不会存在。这代表着一种巨大的潜在节约,因为对于一个典型的程序,4GB的虚拟地址空间的大部分都是未分配的。第二,只有一级页表才需要总是在主存中;虚拟内存系统可以在需要时创建、页面调入或调出二级页表,这就减少了主存的压、力。只有最经常使用的二级页表才需要缓存在主存中。
对于K级的页表层次结构的地址翻译如下:
案例研究: Intel Core i7/Linux内存系统一个运行Linux的Intel Core i7,虽然底层的Haswell微体系结构允许完全的64位虚拟和物理地址空间,而现在(以及可预见的未来)Corei7实现支持48位(256TB)虚拟地址空间和52位(4PB)物理地址空间,还有一个兼容模式,支持32位(4GB)虚拟和物理地址空间。
如果所示给出了Core i7内存系统的重要部分。处理器封装(progressor package)包括四个核,一个大的所有核共享的L3高速缓存,以及一个DDR3内存控制器。每个核包含一个层次结构的TLB,一个层次结构的数据和指令高速缓存,以及一组快速地点到点链路,这种链路基于QuickPath技术,是为了让一个核与其他核和外部I/O桥直接通信。TLB是虚拟寻址的,是四路组相联的。L1,L2和L3高速缓存是物理寻址的,块大小为64字节。L1和L2是8路组相联的。而L3是16组相联的。页大小可以在启动时被配置为4KB或4MB。Linux使用的是4KB的页。
Core i7 地址翻译图9-22总结了完整的Core i7地址翻译过程,从CPU产生虚拟地址的时刻一直到来自内存的数据字到达CPU。Core i7采用四级页表层次结构。每个进程都有它自己私有的页表层次结构。当一个Linux进程在运行时,虽然Core i7体系结构允许页表换进换出,但是与已分配了的页相关联的页表都是驻留在内存中的。CR3控制寄存器指向第一级页表(L1)的起始位置。CR3的值是每个进程上下文的一部分,每次上下文切换时,CR3的值都会被恢复。
下图中给出了第一级,第二级,第三极页表中条目的格式。
当P=1时(Linux中就总是如此),地址字段包含了一个40位物理页号(PPN),它指向适当的页表的开始处。注意,这强加一个要求,要求物理页表4KB对齐。
图9-24给出了第四级页表中条目的格式。当p=1,地址字段包括一个40位PPN,它指向物理内存中某一页的基地址。这又强加了一个要求,要求物理页4KB对齐。
PTE有三个权限位,控制对页的访问。R/W位确定页的内容是可以读写的还是只读的。U/S为确定是否能够在用户模式中访问该页,从而保护操作系统内核中的代码和数据不被用户程序访问。XD(禁止执行)位是在64位系统中引入的,可以用来禁止从某些内存页取指令。这是一个重要的新特性,通过限制只能执行只读代码段,使得操作系统内核降低了缓冲区溢出攻击的风险。
当MMU翻译每一个虚拟地址时,它还会更新另外两个内核缺页处理程序会用到的位每次访问一个页时,MMU都会设置A位,称为引用位(reference bit)。内核可以用这个引用来实现它的页替换算法。每次对一个页进行了写之后,MMU都会设置D位,又称修改位或脏位(dirty bit)。修改位告诉内核在复制替换页之前是否必须写回牺牲页。内核可以通过调用一条特殊的内核模式指令来清除引用位或修改位。
下图给出了Core i7 MMU如何使用四级的页表来将虚拟地址翻译成物理地址。36位VPN被划分成四个9位的片,每个片被用作到一个页表的偏移量。CR3寄存器包含L1页表的物理地址。VPN1提供到一个L1 PET的偏移量,这个PTE包含L2页表的基地址。VPN2提供到一个L2 PTE的偏移量,以此类推。
Linux虚拟内存系统Linux为每个进程维护了一个单独的虚拟地址空间,它包括代码,数据,堆,共享库以及栈段。
内核虚拟内存包括内核中的代码和数据结构。内核虚拟内存的某些区域被映射到所有进程共享的物理页面。例如,每个进程共享内核的代码和全局数据结构。有趣的是,Linux也将一组连续的虚拟页面(大小等于系统中DRAM的总量)映射到相应的一组连续的物理页面。这就为内核提供了一种便利的方法来访问物理内存中任何特定的位置,例如,当它需要访问页表,或一些设备上执行的内存映射的I/O操作,而这些设备被映射到特定的物理内存位置时。
内核虚拟内存的其他区域包含每个进程都不相同的数据。比如说,页表、内核在进程的上下文中执行代码时使用的栈,以及记录虚拟地址空间当前组织的各种数据结构。
Linux虚拟内存区域
Linux将虚拟内存组织成一些区域(也叫做段)的集合。一个区域(area)就是已经乡村音乐存在着的(已分配的)虚拟内存的连续片(chunk),这些也是以某种方式相关联的。例如,代码段,数据段,堆,共享库段,以及用户栈都是不同的区域。每个存在虚拟页面都保存在某个区域中,而不属于某个区域的虚拟页是不存在,并且不能被进程引用。区域的概念很重要,因为它允许虚拟地址空间有间隙。内核不用记录那些不存在的虚拟页,而这样的页也不占用内存、磁盘或者内存本身中的任何额外资源。
图9-27强调了记录一个进程中虚拟内存区域的内核数据结构。内核为系统中的每个进程维护一个单独的任务结构(源代码中的task_struct)。任务结构中的元素包含或者指向内核运行该进程所需要的所有信息(例如,PID,指向用户栈的指针,可执行目标文件的名字,以及程序计数器)。
任务结构中的一个条目指向mm_struct,它描述了虚拟内存的当前状态。我们感兴趣的两个字段是pgd和mmap,其中pgd指向第一级页表(页全局目录)的基址,而mmap指向一个vm_area_structs(区域结构)的链表,其中每个vm_area_structs都描述了当前虚拟地址空间的一个区域。当内核运行这个进程时,就将pgd存放在CR3控制寄存器中。
内存映射Linux通过将一个虚拟内存区域与一个磁盘上的对象(object)关联起来ebates,以初始化这个虚拟内存区域的内容,这个过程称为内存映射(memory mapping)。虚拟内存区域可以映射到两种类型的对象中的一种:
Linux文件系统中的普通文件:一个区域可以映射到一个普通磁盘文件的连续部分,穆赫兰道解析例如一个可执行的目标文件。文件区(section)被分成页大小的片,每一片包含一个虚拟页面的初始内容。因为按需进行页面调度,所以这些虚拟页面没有实际交换进入物理内存,直到CPU第一次引用到页面(即发射一个虚拟地址,落在地址空间这个页面的范围之内)。如果区域比文件区要大,那么就用零来填充这个区域的余下部分。
匿名文件:一个区域也可以映射到一个匿名文件,匿名文件是由内核创建的,包含的全是二进制零。CPU第一次引用这样一个区域内的虚拟页面时,内核就在物理内存中找到一个合适的牺牲页面,网页布局如果该页面被修改过,就将这个页面换出来,用二进制零覆盖牺牲页面并更新页面,如果该页面标记为是驻留在内存中的。注意在磁盘和内存之间并没有实际的数据传送。因为这个原因,映射到匿名文件的区域中的页面有时也叫做请求二进制零的页(demand-zero page)。
无论哪种情况下,一旦一个虚拟页面被初始化了,它就在一个由内核维护的专门的交换文件(swap file)之间换来换去。交换文件也叫作交换空间(swap space)或者交换区域(swap area)。需黄金分析软件要意识到的很重要的一点是,在任何时刻,交换空间都限制着当前运行着的进程能够分配的虚拟页面的总数。
小结虚拟内存是对主存的一个抽象。支持虚拟内存的处理器通过使用一种叫做虚拟寻址的间接形式来引用主存。处理器产生一个虚拟地址,在被送到主存之前,这个地址被翻译成一个物理地址。从虚拟地址空间到物理地址空间的地址翻译要求应硬件和软件紧密合作。专门的硬件通过使用页表来翻译虚拟地址,而页表的内容是由操作提供的。
虚拟内存提供三个重要的功能。第一,它在主存中自动缓存最近使用的存放磁盘上的虚拟地址空间的内容。虚拟内存缓存中的块叫做页。对磁盘上页的引用会触发缺乏,缺页将控制转移到操作系统中的一个缺页处理程序。缺页处理程序将页面从磁盘复制到主存缓存,如果必要,将写回被驱逐的页。第二,虚拟内存简化了内存管理,进而又简化了链接,在进程间共享数据,进程的内存分配以及程序加载。最后,虚拟内存通过在每条页表条目加入保护位,从而简化了内存保护。
地址翻译的过程必须和系统中所有的硬件缓存的操作集成在一起。大多数页表条目位于L1高速缓存中,但是一个称为TLB的页表条目的片上高速缓存,通常会消除访问在L1上的页表条目的开销。
现代系统通过将虚拟内存片和磁盘上的文件片关联起来,来初始化虚拟内存片,这个过程称为内存映射。内存映射为共享数据、创建新的进程以及加载程序提供了一种高效的机制。应用可以使用mmap函数来手工地创建和删除虚拟地址空间的区域。然而,大多数程序依赖于动态内存分配器,例如malloc,它管理虚拟地址空间区域内一个称为堆的区域。动态内存分配器是一个感觉像系统级程序的应用级程序,它直接操作内存,而无需类型系统的很多帮助。分配器有两种类型。显示分配器要求应用显示释放它们的内存块。隐式分配器(垃圾收集器)自动释放任何未使用的和不可达的块。
对于C程序员来说,管理和使用虚拟内存苏宁618是一件困难和容易出错的任务。常见的错误示例包括:间接引用坏指针,读取未初始化的内存,允许栈电机驱动缓冲区溢出,假设指针和它们指向的对象大小相同,引用指针而不是它所指向的对象,误解指针运算,引用不存在的变量,以及引起内存泄漏。
MMU即内存管理单元(Memory Manage Unit),是一个与软件密切相关的硬件部件,也是理解linux等操作系统内核机制的最大障碍之一。可以说,不懂MMU使很多人一直停滞在单片机与无OS的时代。博主之前对MMU也一直是雾里看情侣手链花,似懂非懂。最近终于自认为云开雾散后,回头总结,感觉有几个概念是阻碍人们理解MMU的元凶。1)虚拟地址/物理地址如果处理器没有MMU,CPU内部执肩周炎如何治疗行单元产生的内存地址信号将直接通过地址总线发送到芯片引脚,被内存芯片接收,这就是物理地址(physical address),简称PA。英文physical代表物理的接触,所以PA就是与内存芯片physically connected的总线上的信号。如果MMU存在且启用,CPU执行单元产生的地址信号在发送到内存芯片之前将被MMU截获,这个地址信号称为虚拟地址(virtual address),简称VA,MMU会负责把VA翻译成另一个地址,然后发到内存芯片地址引脚上,即VA映射成PA,如下图:
所以物理地址①是通过CPU对外地址总线②传给Memory Chip③使用的地址;而虚拟地址④是CPU内部执行单元⑤产生的,发送给MMU⑥的地址。硬件上MMU⑥一般封装于CPU芯片⑦内部,所以虚拟地址④一般只存在于CPU⑦内部,到了CPU外部地址总线引脚上②的信号就是MMU转换过的物理地址①。软件上MMU对用户程序不可见,在启用MMU的平台上(没有MMU不必说,只有物理地址,不存在虚拟地址),用户C程序中变量和函数背后的数据/指令地址等都是虚拟地址,这些虚拟内存地址从CPU执行单元⑤发出后,都会首先被MMU拦截并转换成物理地址,然后再发送给内存。也就是说用户程序运行*pA =100;”这条赋值语句时,假设debugger显示指针pA的值为0x30004000(虚拟地址),但此时通过硬件工具(如逻辑分析仪)侦测到的CPU与外存芯片间总线信号很可能是另外一个值,如0x8000(物理地址)。当然对一般程序员来说,只要上述语句运行后debugger显示0x30004000位置处的内存值为100就行了,根本无需关心pA的物理地址是多少。但进行OS移植或驱动开发的系统程序员不同,他们必须清楚软件如何在幕后辅助硬件MMU完成地址转换。2)页/页帧/页表/页表项(PTE)这几个页概念也噎倒了不少人,这里澄清下。MMU是负责把乌龙茶有哪些虚拟地址映射为物理地址,但凡”映射”都要解决两个问题:映射的最小单位(粒度)和映射的规则。MMU中VA到PA映射的最小单位称为页(Page),映射的最低粒度是单个虚拟页到物理页,页大小通常是4K,即一次最少要把4K大小的VA页块整体映射到4K的PA页块(从0开始4K对齐划分页块),页内偏移不变,如VA的一页0x30004000~0x30004fff被映射到PA的一页 0x00008000~0x00008fff,当CPU执行单元访问虚拟地址0x30004008,实际访问的物理地址是0x00008008(0x30004008和0x00008008分别位于虚实两套地址空间,互不相干,不存在重叠和冲突)。以页为最小单位,就是不能把VA中某一页划分成几小块分别映射到不同PA,也不能把VA中属于不同页的碎块映射到PA某一页的不同部分,必须页对页整体映射。页帧(Page Frame)是指物理内存中的一页内存,MMU虚实地址映射就是寻找物理页帧的过程,对这个概念了解就可以了。MMU软件配置的核心是页表(Page Table),它描述MMU的映射规则,即虚拟内存哪(几)个页映射到物理内存哪(几)个页帧。页表由一条条代表映射规则的记录组成,每一条称为一个页表条目(Page Table Entry,即PTE),整个页表保存在片外内存,MMU通过查找页表确定一个VA应该映射到什么PA,以及是否有权限映射。但如果MMU每次地址转换都到位于外部内存的页表上查找PTE,转换速度就会大大降低,于是出现了3)TLBTLB (Translation Lookaside Buffers)即转换快表,又简称快表,可以理解为MMU内部专用的存放页表的cache,保存着最近使用的PTE乃至全部页表。MMU接收到虚拟地址后,首先在TLB中查找,如果找到该VA对应的PTE就直接转换,找不到再去外存页表查找,并置换进TLB。TLB属于片上SRAM,访问速度快,通过TLB缓存PTE可以节省MMU访问外存页表的时间,从而加速虚实地址转换。TLB和CPU cache的工作原理一样,只是TLB专用于为MMU缓存页表。4)MMU的内存保护功能既然所有发往内存的地址信号都要经过MMU处理,那让它只单单做地址转换,岂不是浪费了这个特意安插的转换层?显然它有能力对虚地址访问做更多的限定(就像路由器转发网络包的同时还能过滤各种非法访问),比如内存保护。可以在PTE条目中预留出几个比特,用于设置访问权限的属性,如禁止访问、可读、可写和可执行等。设好后,CPU访问一个VA时,MMU找到页表中对应PTE,把指令的权限需求与该PTE中的限定条件做比对,若符合要求就把VA转换成PA,否则不允许访问,并产生异常。5)多级页表虚拟地址由页号和页内偏移组成。什么东东呢?前面说过MMU映射以页为最小单位,假设页大小为4K(212),那么无论页表怎样设置,虚拟地址后12比特与MMU映射后的物理地址后12比特总是相同,这不变的比特位就是页内偏移。为什么不变?如何除甲醛拜托,把搭积木想象成一种映射,不管你怎么搭,你也改变不了每块积木内部的原子排列吧。所谓以页为最小单位就是保持一部分不变作为最小粒度。页号就更有故事了,一个32bits虚拟地址,可以划分为220个内存页,如果都以页为单位和物理页帧随意映射,页表的空间占用就是220*sizeof(PTE)*进程数(每个进程都要有自己的页表),PTE一般占4字节,即每进程4M,这对空间占用和MMU查询速度都很不利。问题是实际应用中不需要每次都按最小粒度的页来映射,很多时候可以映射更大的内存块。因此最好采用变化的映射粒度,既灵活又可以减小页表空间。具体说可以把20bits的页号再划分为几部分(如下图linux的3级划分)
简单说每次MMU根据虚拟地址查询页表都是一级级进行,先根据PGD的值查询,如果查到PGD的匹配,但后续PMD和PTE没有,就以2(offset+pte+pmd)=1M为粒度进行映射,后20bits全部是块内偏移,与物理地址相同。6)操作系统和MMU实际上MMU是为满足操作系统越来越复杂的内存管理而产生的。OS和MMU的关系简单说:a.系统初始化代码会在内存中生成页表,然后把页表地址设置给MMU对应寄存器,使MMU知道页表在物理内存中的什么位置,以便在需要时进行查找。之后通过专用指令启动MMU,以此为分界,之后程序中所有内存地址都变成虚地址,MMU硬件开始自动完成查表和虚实地址转换。b.OS初始化后期,创建第一个用户进程,这个过程中也需要创建页表,把其地址赋给进程结构体中某指针成员变量。即每个进程都要有独立的页表。c.用户创建新进程时,子进程拷贝一份父进程的页表,之后随着程序运行,页表内容逐渐更新变化。比较复杂了,几句讲不清楚,不多说了哈,有时间讲linux的话再说吧
总结:(1)当存在mmu时,存在两种地址,物理地址和虚拟地址(2)虚拟地址的大小由CPU的位数决定(3)对用户而言,操作的地址都是虚拟地址(4)虚拟地址在从cpu发到外部地址总线上时,会先被mmu截获,mmu经过映射后产生物理地址,再发送到外部的地址总线上(5)MMU得到虚拟地址后先在TLB内查找,若没找到匹配的PTE条目就到外部页表查询,并置换进TLB;根据PTE条目中对访问权限的限定检查该条VA指令是否符合,若不符合则不继续,并抛出exception异常;符合后根据VA的地址分段查询页表,保持offset(广义)不变,组合出物理地址,发送出去。
本文发布于:2023-06-04 09:15:59,感谢您对本站的认可!
本文链接:http://www.ranqi119.com/ge/85/215293.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |