#Windows内核学习记录#
tip:PAE模式扩展虚拟内存
-
页模式:
虚拟内存与物理内存通过映射表关联
虚拟内存以“页”为最小单位,对应物理内存的“页帧”
虚拟内存中的页不一定实时存在一个物理页帧与其对应,实现了物理内存的动态分配
-
gpt说明:
通常情况下,虚拟内存页的大小是物理内存页帧大小的整数倍。这种倍数关系有助于简化内存管理和地址转换的过程。
例如,在x86体系结构中,常见的虚拟内存页大小是4KB,而常见的物理内存页帧大小也是4KB。这种情况下,虚拟页和物理页之间是一一对应的,地址转换非常简单。如果虚拟内存页大小是物理内存页帧大小的整数倍,那么虚拟地址和物理地址之间的转换就会更加高效。
然而,有些情况下,虚拟内存页的大小可能会大于物理内存页帧的大小,这被称为"大页"或"大页面"。这可以提高内存管理的性能,减少页表的大小,但会占用更多的虚拟内存空间。在这种情况下,虚拟内存页的大小不是物理内存页帧大小的整数倍。
总之,虚拟内存页和物理内存页帧之间是否有倍数关系取决于操作系统的配置和需求,但通常情况下,它们会被设置为整数倍关系以简化地址转换和提高性能。
虚拟地址的作用:
索引指定一个物理页,偏移决定具体位置:
x86的寻址方式
高10位为目录索引,中10位为页表索引,低10位为页内偏移
其实每个索引都相当于一个偏移
下面阐述一个虚拟地址到物理地址的映射
例如:对于虚拟地址0x0040A123
0x0040A123 & 0xFFC00000 = 0x00400000 → 页目录索引(PDE)
0x0040A123 & 0x003FF000 = 0x0000A000 →页表索引(PTE)
0x0040A123 & 0x00000FFF = 0x00000123 →物理偏移
先从CR3寄存器中获取页目录的基地址,
加上页目录索引确定一个位置,取出该位置中的值,
将这个值作为页表的基地址,
加上页表索引,确定页表中的一个位置,取出该位置中的值,
将该值作为物理地址的基地址,加上物理地址偏移,得到一个物理地址
按10个位划分,所以一个页目录项可表示1024个页表项,同理一个页表项可以表示1024个物理地址基址的范围。(每个项中表示的大小均为4字节,32位,所以大小为1024*4)
目录项和页表项均指向一个 32 位地址,但只有前 20 位真正指向一个物 理地址,后 12 位用于各种标志信息,比如页面是否已被访问过、是否允许缓存等。
一个进程对应一个页目录,页目录由操作系统维护
当多次查询一个物理地址时,该地址被存入地址转译快查缓冲区(TLB),方便快速查询信息,避免二次访问内存浪费时间(进程没有切换时)
-
-
段模式:
实模式下的寻址模式方式时,段寄存器的16位作为段地址,加上偏移地址可得实际地址(段地址左移一位 + 偏移地址 = 20位实地址,因为当时的地址线为20位)
保护模式下的段模式,段寄存器仍然为16位,高13位 * 8得到一个偏移地址(实际上可能是一些比较小的索引数字),加上gdtr或ldtr中的基地址,取得段描述符表中的一个段描述符,
一个段描述符有4个字节大小(32位,在32位的操作系统下正好是一个字的大小),其中包含了段的基地址,加上外界获取的Offect则可表示一个实际地址,这种方式计算出的是线性地址即页模式中的虚拟地址
总结:
处理器在解析一个“段+偏移”的逻辑地址时,首先根据段寄存器中的表指示位确定 应该使用 GDT(若表指示位为 0)还是 LDT(表指示位为 1),然后从 gdtr 或 ldtr 中得到 描述符表的地址,再加上段索引部分乘以 8,即得到段描述符的地址,然后根据段描述符 的格式,拼出 32 位段基地址,最后加上 CPU 指令中的偏移值,得到最终的线性地址。在 实际执行指令过程中,每个段寄存器内部都有一个 8 字节的缓存(或称为内部寄存器), 存放了对应于段寄存器的段描述符,如果段寄存器没有改变,则以上的地址计算过程可以 省略查描述符表的步骤,从而直接在处理器内部计算出线性地址。
线性地址即虚拟地址
-
最后需要说明的是,段式内存管理和页式内存管理并不是对立的,它们可以组合起来 在同一个系统中使用