Linux 核心--4.内存管理(3) Linux使用最近最少使用(LRU)页面衰老算法来公平地选择将要从系统中抛弃的页面。这种策略为系统中的每个页面设置一个年龄,它随页面访问次数而变化。页面被访问的次数越多则页面年龄越年轻;相反则越衰老。年龄较老的页面是待交换页面的最佳侯选者。 3.1.3 共享虚拟内存 虚拟内存让多个进程之间可以方便地共享内存。所有的内存访问都是通过每个进程自身的页表进行。对于两个共享同一物理页面的进程,在各自的页表中必须包含有指向这一物理页面框号的页表入口。 图3.1中两个进程共享物理页面框号4。对进程X来说其对应的虚拟页面框号为4而进程Y的为6。这个有趣的现象说明:共享物理页面的进程对应此页面的虚拟内存位置可以不同。 3.1.4 物理与虚拟寻址模式 操作系统自身也运行在虚拟内存中的意义不大。如果操作系统被迫维护自身的页表那将是一个令人恶心的方案。多数通用处理器同时支持物理寻址和虚拟寻址模式。物理寻址模式无需页表的参与且处理器不会进行任何地址转换。Linux核心直接运行在物理地址空间上。 Alpha AXP处理器没有特殊的物理寻址模式。它将内存空间划分为几个区域并将其中两个指定为物理映射地址。核心地址空间被称为KSEG地址空间,它位于地址0xfffffc0000000000以上区域。为了执行位于KSEG的核心代码或访问那里的数据,代码必须在核心模式下执行。Alpha上的Linux核心从地址0xfffffc0000310000开始执行. 3.1.5 访问控制 页表入口包含了访问控制信息。由于处理器已经将页表入口作为虚拟地址到物理地址的映射,那么可以很方便地使用访问控制信息来判断处理器是否在以其应有的方式来访问内存。 诸多因素使得有必要严格控制对内存区域的访问。有些内存,如包含执行代码的部分,显然应该是只读的,操作系统决不能允许进程对此区域的写操作。相反包含数据的页面应该是可写的, 但是去执行这段数据肯定将导致错误发生。多数处理器至少有两种执行方式:核心态与用户态。任何人都不会允许在用户态下执行核心代码或者在用户态下修改核心数据结构。 图3.2 Alpha AXP页表入口 页表入口中的访问控制信息是处理器相关的;图3.2是Alpha AXP处理器的PTE(Page Table Entry)。这些位域的含义如下: V 有效,如果此位置位,表明此PTE有效 FOE “执行时失效”,无论合时只要执行包含在此页面中的指令,处理器都将报告页面错误并将控制传递 FOW “写时失效”, 除了页面错误发生在对此页面的写时,其他与上相同。 FOR “读时失效”,除了页面错误发生在对此页面的读时,其他与上相同。 ASM 地址空间匹配。被操作系统用于清洗转换缓冲中的某些入口。 KRE 运行在核心模式下的代码可以读此页面。 URE 运行在用户模式下的代码可以读此页面。 GH 将整个块映射到单个而不是多个转换缓冲时的隐含粒度。 KWE 运行在核心模式下的代码可以写此页面。 UWE 运行在用户模式下的代码可以写此页面。 page frame number 对于V位置位的PTE,此域包含了对应此PTE的物理页面框号;对于无效PTE,此域不为0,它包含了页面在交换文件中位置的信息。 以下两位由Linux定义并使用。 _PAGE_DIRTY 如果置位,此页面要被写入交换文件。 _PAGE_AccessED Linux用它表示页面已经被访问过。 3.2 高速缓冲 如果用上述理论模型来实现一个系统,它可能可以工作,但效率不会高。操作系统设计者和处理器设计者都在努力以提高系统的性能。除了制造更快的CPU和内存外,最好的办法是在高速缓冲中维护有用信息和数据以加快某些操作。Linux使用了许多与高速缓冲相关的内存管理策略。 Buffer Cache 这个buffer cache中包含了被块设备驱动使用的数据缓冲。