您好、欢迎来到现金彩票网!
当前位置:一品彩票app下载 > 共享页表 >

Linux页表中虚拟内存地址如何映射到硬盘数据块地址?

发布时间:2019-06-16 06:09 来源:未知 编辑:admin

  当页表发现虚拟内存的内容不在物理内存中会发生缺页,这时候,需要把硬盘上某个数据块读入内存,并修改页表。问题是,内核怎么指定需要去读取磁盘上的哪一个数据块呢?虚拟内存如果映射的是物理内存,那么页表的内容是物理内存地址,那么如果映射的是磁盘数据块,那么页表的内容是什么呢? 类似问题:Linux内核是如何管理内存的换入换出,以及是如何实现磁盘缓存的?

  Linux页表中虚拟内存地址如何映射到硬盘数据块地址?显然这个问题是不对的,CPU没有直接访问磁盘的能力,CPU页表里填的永远是内存地址,除非这个磁盘是挂到地址总线上,而且可以像普通内存一样访问。

  Linux进程地址空间可以分成两大类,文件映射和匿名映射。文件映射,顾名思义,是指该地址空间的内容来自于一个文件;而匿名映射地址空间背后什么靠山都没有。进程的代码段来自于镜像,采用文件映射方式;而栈,堆,bss段,数据段均是匿名映射。

  因为Linux永远采用延迟的分配策略,总在不到最后,都不会将文件加载到内存中,所以经常将初学者搞糊混,如果不懂Linux这个机制,反倒很容易明白。所以,我们是不是钻进一个细节里面,反倒是把OS的承诺给忘了(OS内部的延迟机制对用户态进程永远是透明的,不需要感知)。

  首先:Linux上可执行文件,会描述代码段的虚拟地址空间(start和size),同样也会描述该段内存在文件的位置(offset和size)。

  然后:Linux加载进程时(exec系列系统调用)会为该地址空间分配一个 VMA,vma数据结构会描述虚拟空间的开始地址,以及空间大小,同时会描述该vma背后映射的文件名(或路径)、映射空间所在文件的偏移量和大小。但是Linux内核不给该空间分配物理内存,所以此时的页表项是空的。当vma设置好之后,就算加载完事了,跳到main函数开始执行。

  再后:当一旦执该代码段时,由于页表项不存在,CPU会产生一次违例访存,跳进OS早早就调置好的缺页异常代码(do_page_fault),在do_page_fault函数内经过严密的安检之后,确认程序访存的合法性之后,就要将文件加载到内存中。

  接着:do_page_fault根据vma里面描述的文件名,调用文系统接口将文件内存加载到物理内存中。等等……这个过程也涉及很复杂的加载过程,涉及磁盘访问,bio,以及pagecache,可以在知乎上找很多相关的描述。

  最后:文件加载到物理内存(就是pagecache)后,可以修改页表项了,将页有的PFN填写成物理内存的页框号,访问属性等一系的页表位写之后,就算完了,返回用户态。继续执行。

  你可以交换出去一定有个vma描述这个交换区,上面有swap_info_struct描述交换区信息,你直接去代码里搜关于这个结构的读写就全都出来了。我就不帮你贴代码了。

  唐浩然:Linux内核是如何管理内存的换入换出,以及是如何实现磁盘缓存的?

  其实Linux的实现很简单,对于每个进程来说,每段内存段,比如映射的文件的内存段,都用一个VMA来描述,VMA结构体中,有一个file指针指向它的backend硬盘文件。当user space进程访问此地址产生缺页中断后,会陷入内核态将硬盘文件里的内容准备好,程序就可以继续执行了。不知道有没有回答好你的问题?

  1、只有当缺页发生在进程的代码段和数据段时,才会从磁盘中读4KB数据加载到内存(一个物理页);

  2、若发生在进程地址空间的其他地方(堆、栈空间),则直接申请一个空闲物理页,将该物理页与发生中断的线性页建立映射关系。

  因此,题主应该指的是第一种情况。进程代码段和数据段在磁盘中保存在该进程的二进制可执行文件中,而该文件的位置由进程描述符中有一个字段间接的指向。所以,当发生缺页中断后,OS通过该字段找到进程相应的二进制可执行文件,然后进行加载操作。

  1、首先,“页表的内容是物理内存地址”描述不太精确,但是核心意思没有问题。所以页表中页表项的内容不可能和“磁盘数据块”有任何直接关系。

  2、题主的问题中,涉及到3个对象,虚拟内存(线性页)、物理内存(物理页、内存缓冲块)和磁盘数据块。这三者可以有的映射关系有两个,线性页--物理页;内存缓冲块--磁盘数据块。前者的映射关系保存在页表的页表项中;后者的保存在OS的专门的数据结构中。

  我来回答一下,不确定对不对。首先每个进程都有自己的名字空间,你说当发现需要的数据不在物理内存中的时候需要去磁盘读取数据到内存中!这个问题是首先进程是知道自己需要什么数据的,它才知道这些数据在不在物理内存中!这些数据是什么呢?比如说文件的元数据这是很重要的,经常都是缓存在内存中!额如果说元数据你不知道是什么的话,那这么说吧。比如说文件的数据你第一次读取的时候有部分是缓存在内存中的,以免你过一会就又重新读取这个文件(当然存在内存的时间看各种操作系统自己的机制啦,比如有的10ms就将数据刷回硬盘)。。继续,然后,你再次读取这个文件,然后内核发现该文件数据有部分存储在内存中,可是有的不在!重点来了,意思是内核知道不在内存中的这部分数据是磁盘的哪部分数据的,因此就会去磁盘对应位置读取这部分不在内存中的数据。

  额,如果你非要问内核怎么知道这部分不在内存中的数据在磁盘的什么位置的话。。这。。说起来就很复杂啦。。每个文件在内存中有自己的一个address space 维护还文件的一颗radix-tree 这棵树就描述着这个文件的磁盘数据在磁盘的位置与物理内存page的对应关系(这样说也不是很对。。可以这么理解)。。内核发现要读取的这个文件的某个位置的数据对应的page不在这棵树上(这样说也不是很对,你就这么理解吧)。。然后就会提交一个申请块的bio 去磁盘申请数据去啦。。哎呀打完了。不对的地方求指教!

  什么是虚存?为什么需求它? 咱们知道程序代码和数据有必要驻留在内存中才干得以运转,可是体系内 存数量很有限,往往不能包容一个完好程序的一切代码和数据,更何况在多使命体系中,可能需求一起翻开子处理程序,画图程序,浏览器等许多使命,想让内存驻 留一切这些程序明显不太可能。因而首先能想到的就是将程序分割成小份,只让当时体系运转它一切需求的那部分留在内存,其它部分都留在硬盘。当体系处理完当 前使命片段后,再从外存中调入下一个待运转的使命片段。的确,旧式体系就是这样处理大使命的,而且这个作业是由程序员自行完结。可是跟着程序语言越来越高 级,程序员对体系体系的依靠程度下降了,很少有程序员能十分清楚的驾御体系体系,因而甩手让程序员担任将程序片段化和按需调入轻则下降功率,重则使得机器 崩溃;再一个原因是跟着程序越来越丰厚,程序的行为简直无法精确猜测,程序员自己都很难判断下一步需求载入哪段程序。因而很难再靠预见性来静态分配固定大 小的内存,然后再机械地轮换程序片进入内存履行。体系有必要采纳一种能按需分配而不需求程序员干涉的新技能。 虚拟内存(之所以称为虚 拟内存,是和体系中的逻辑内存和物理内存相对而言的,逻辑内存是站在进程视点看到的内存,因而是程序员关怀的内容。而物理内存是站在处理器视点看到的内 存,由操作体系担任办理。虚拟内存能够说是映射到这两种不同视角内存的一个技能手段。)技能就是一种由操作体系接管的按需动态内存分配的办法,它允许程序 不知不觉中运用大于实践物理空间巨细的存储空间(其实是将程序需求的存储空间以页的方式分散存储在物理内存和磁盘上),所以说虚拟内存彻底解放了程序员, 从此程序员不用过分关怀程序的巨细和载入,能够自在编写程序了,繁琐的作业都交给操作体系去做吧。 完成虚拟内存 虚拟内存是将体系硬盘空间和体系实践内存联合在一起供进程运用,给进程供给了一个比内存大得多的虚拟空间。在程序运转时,只要把虚拟地址空间的一小部分 映射到内存,其他都存储在硬盘上(也就是说程序虚拟空间就等于实践物理内存加部分硬盘空间)。当被拜访的虚拟地址不在内存时,则阐明该地址未被映射到内 存,而是被存贮在硬盘中,因而需求的虚拟存储地址随即被调入到内存;一起当体系内存严重时,也能够把当时不用的虚拟存储空间换出到硬盘,来腾出物理内存空 间。体系如此循环往复地运转——换入、换出,而用户简直无法查觉,这都是拜虚拟内存机制所赐。 Linux的swap分区就是硬盘专门为虚拟存储空间预留的空间。经验巨细应该是内存的两倍左右。有爱好的话能够运用 swapon -s 查看交流分区巨细。 大道理很好了解,无非是用内存和硬盘空间合成为虚拟内存空间。可是这一进程中重复运转的地址映射(虚拟地址映射到物理地址)和虚拟地址换入换出却值得细心琢磨。体系到底是怎么样把虚拟地址映射到物理地址上的呢?内存又怎么能不断地和硬盘之间换入换出虚拟地址呢? 运用段机制能否答复上述问题呢?逻辑地址经过段机制后变为一个32位的地址,足以掩盖4G的内存空间,当程序需求的虚拟地址不在内存时,只依靠段机制很 难进行虚拟空间地换入换出,由于不大便利把整段巨细的虚拟空间在内存和硬盘之间调来调去(旧式体系中,会蠢笨地换出整段内存甚至整个进程,想想这样做会有 那些后果吧!)。所以很有必要寻觅一个更小更灵敏的存储表明单位,这样才便利虚拟地址在硬盘和内存之间调入调出。这个更小的存储办理单位便是页(4K大 小)。办理页换入换出的机制被称为页机制。 由于运用页机制的原因,经过段机制变换得到的地址只是是作为一个中心地址——线性地址, 该地址不代表实践物理地址,而是代表整个进程的虚拟空间地址。在线性地址的基础上,页机制接着会处理线性地址映射:当需求的线性地址(虚拟空间地址)不在 内存时,便以页为单位从磁盘中调入需求的虚拟内存;当内存不行时,又会以页为单位把内存中虚拟空间的换出到磁盘上。可见,运用页来办理内存和磁盘(虚拟内 存)大大便利了内存办理的作业。毫无疑问,页机制和虚拟内存办理简直是“绝配”。 运用页机制,4G空间被分红2的20次方个4K巨细的 页面(页面也可定为4M巨细),因而定位页面需求的索引表(页表)中每个索引项至少需求20位,可是在页表项中往往还需求附加一些页特点,所以页表项实践 为32位,其中12位用来寄存比方“页是否存在于内存”或“页的权限”等信息。 前面咱们提到了线位则给出了页面中的偏移。线性地址经过页表找到页面基地址后和低12位偏移量相加就形成了终究需求的物理地址了。 在实践运用中,并非一切页表项都是被寄存在一个大页表里,由于每个页表项占4个字节,假如要在一个表中寄存2的20次方个页表项,就需求4M的接连存储空间。这么大的接连空间可不好找,因而往往会把页表分级存储,比方分两级,那么每级页表只需求4k接连空间了。 两级页表查找好像看章回小说,先找到在哪一章里,然后在找在该章下的哪一节。详细进程看看下图: 综上所述,地址变换作业需求两种技能,一是段机制,二是页机制。段机制处理逻辑地址向线性地址的映射;页机制则担任把线性地址映射为物理地址。两级映射共同完结了从程序员看到的逻辑地址变换到处理器看到的物理地址这一艰巨使命。 你能够将这两种机制别离比作一个地址变换函数,段机制的变量是逻辑地址,函数值是线性地址;页机制的变量是线性地址,函数值是物理地址。地址变换进程如下所示。 逻辑地址——(段函数)——线性地址——(页函数)——物理地址。 尽管段机制和页机制都参与映射,但它们分工不同,而且彼此独立互不搅扰,彼此之间不用知道对方是否存在。 下面咱们结合Linux实例简要地看看段页机制怎么运用。 Linux中的分段战略 段机制在Linux里用得有限,并没有被彻底运用。每个使命并未别离组织各自独立的数据段,代码段,而是只是最低极限的运用段机制来阻隔用户数据和体系 数据——Linux只组织了四个规模相同的段,内核数据段,内核代码段,用户数据段,用户代码段,它们都掩盖0-4G的空间,所不同的是各段特点不同,内 核段特权级为0,用户段特权级为3。这样分段,避免了逻辑地址到线性地址的变换步骤(逻辑地址就等于线性地址),但仍然保留了段的等级这层最基本维护。 每个用户进程都能够看到4G巨细的线G是用户空间,用户态进程能够直接拜访;从3G-4G空间为内核空间,寄存内核代码和数据,只要内核态进程能够直接拜访,用户态进程不能直接拜访,只能经过体系调用和中止进入内核空间,而这时就要进行的特权切换。 说 到特权切换,就离不开使命门,圈套门/中止门等概念。圈套门和中止门是在发作圈套和中止时,进入内核空间的通道。调用门是用户空间程序彼此拜访时所需求的 通道,使命门比较特别,它不含任何地址,而是服务于使命切换(但linux使命切换时并未真实采用它,它太麻烦了)。 关于各种门体系都会有对应的门描述符,和段描述符结构相似,门描述符也是由对应的门选择字索引,而且终究会产生一个指向特定段内偏移地址的指针。这个指针指向的就是即将进入的进口。运用门的意图就是确保进口可控,不至于进入到内核中不应拜访的位置。 Linux中的分页战略 看看linux中怎么运用分页。 Linux中每个进程都会有各自不同的页表,也就是说进程的映射函数互不相同,确保每个进程虚拟地址不会映射到相同的物理地址上。这是由于进程之间有必要彼此独立,各自的数据有必要阻隔,避免信息走漏。 需求注意的是,内核作为有必要维护的独自部分,它有自己独立的页表来映射内核空间(并非悉数空间,只是是物理内存巨细的空间),该页表 (swapper_pg_dir)被静态分配,它只来映射内核空间(swapper_pg_dir只用到768项今后的项——768个页目录可映射3G空 间)。这个独立页表确保了内核虚拟空间独立于其他用户程序空间,也就是说其他进程一般状态下和内核是没有联络的(在编译内核的时候,内核代码被指定链接到 3G以上空间),因而内核数据也就自然被维护起来了。 那么在用户进程需求拜访内核空间时怎么做呢? Linux采用了个奇妙的办法:用户进程页表的前768项映射进程空间(3G,由于LDT 中只指定基地址为0,规模只能到0xc0000000),假如进程要拜访内核空间,如调用体系调用,则进程的页目录中768项后的表项将指向 swapper_pg_dir的768项后的项,所以一旦用户陷入内核,就开始运用内核的页表swapper_pg_dir了,也就是说能够拜访内核空间 了。以Windows 7为例,计算机右键,特点,高档体系设置,性能设置...,高档,虚拟内存更改...,主动办理取消,自定义巨细,设置,断定,退出重启。 内存为2G及以上的,一般能够禁用虚拟内存(有软件限制的能够设少数虚拟内存,如2G至4G)。部分的确会运用很多内存的人,如玩大型3D游戏、制造大幅图片、3D建模等,并收到体系内存不足警告的,才需求酌情设定虚拟内存。

http://styleinch.com/gongxiangyebiao/463.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有