x86分页是如何工作的?
这个问题是为了填补关于这个主题的免费信息的空白 我相信一个好的答案会适合一个大的SO答案,或者至少适合几个答案 主要目标是为完全初学者提供足够的信息,以便他们能够自己阅读手册,并能够理解与分页相关的基本操作系统概念 建议的准则:x86分页是如何工作的?,x86,paging,virtual-memory,X86,Paging,Virtual Memory,这个问题是为了填补关于这个主题的免费信息的空白 我相信一个好的答案会适合一个大的SO答案,或者至少适合几个答案 主要目标是为完全初学者提供足够的信息,以便他们能够自己阅读手册,并能够理解与分页相关的基本操作系统概念 建议的准则: 答案应该对初学者友好: 具体但可能简化的示例非常重要 欢迎应用所示概念 引用有用的资源是好的 对于OSs如何使用分页功能的一些小离题是受欢迎的 欢迎提供PAE和PSE解释 欢迎您将小的内容转移到x86_64中 相关问题以及为什么我认为他们不是傻瓜: :标题与此
- 答案应该对初学者友好:
- 具体但可能简化的示例非常重要
- 欢迎应用所示概念
- 引用有用的资源是好的
- 对于OSs如何使用分页功能的一些小离题是受欢迎的
- 欢迎提供PAE和PSE解释
- 欢迎您将小的内容转移到x86_64中
- :标题与此问题几乎相同,但正文提出了与cr3和TLB相关的具体问题。那个问题是这个问题的一个子集
- :body仅请求源
mov eax,[rsi]
中rsi
的内容)
首先分段将它们转换为线性地址,然后分页将线性地址转换为物理地址
(logical) ------------------> (linear) ------------> (physical)
segmentation paging
大多数情况下,我们可以将物理地址视为索引实际RAM硬件内存单元,但这并非100%正确,因为:
cr0
寄存器的PG
位,则分页处于打开状态
分页与分段
分页和分段之间的一个主要区别是:
- 分页将RAM分成大小相等的块,称为页
- 分段将内存分割为任意大小的块
- 两个程序都不需要了解另一个
- 两个程序的内存都可以根据需要增减
- 程序之间的切换非常快
- 一个程序永远不能访问另一个进程的内存
cr3
)
其他一些体系结构将分页几乎完全交给了软件,因此TLB未命中将运行操作系统提供的函数来遍历页表并将新映射插入TLB。这使得页表格式由操作系统选择,但使其变得更容易
示例:简化的单级分页方案
这是一个分页如何在简化版本的x86体系结构上运行的示例
实现虚拟内存空间
页表
操作系统可以为他们提供以下页面表:
操作系统提供给进程1的页表:
RAM location physical address present
----------------- ----------------- --------
PT1 + 0 * L 0x00001 1
PT1 + 1 * L 0x00000 1
PT1 + 2 * L 0x00003 1
PT1 + 3 * L 0
... ...
PT1 + 0xFFFFF * L 0x00005 1
RAM location physical address present
----------------- ----------------- --------
PT2 + 0 * L 0x0000A 1
PT2 + 1 * L 0x0000B 1
PT2 + 2 * L 0
PT2 + 3 * L 0x00003 1
... ... ...
PT2 + 0xFFFFF * L 0x00004 1
RAM location physical address present
--------------- ----------------- --------
PD1 + 0 * L 0x10000 1
PD1 + 1 * L 0
PD1 + 2 * L 0x80000 1
PD1 + 3 * L 0
... ...
PD1 + 0x3FF * L 0
操作系统提供给进程2的页表:
RAM location physical address present
----------------- ----------------- --------
PT1 + 0 * L 0x00001 1
PT1 + 1 * L 0x00000 1
PT1 + 2 * L 0x00003 1
PT1 + 3 * L 0
... ...
PT1 + 0xFFFFF * L 0x00005 1
RAM location physical address present
----------------- ----------------- --------
PT2 + 0 * L 0x0000A 1
PT2 + 1 * L 0x0000B 1
PT2 + 2 * L 0
PT2 + 3 * L 0x00003 1
... ... ...
PT2 + 0xFFFFF * L 0x00004 1
RAM location physical address present
--------------- ----------------- --------
PD1 + 0 * L 0x10000 1
PD1 + 1 * L 0
PD1 + 2 * L 0x80000 1
PD1 + 3 * L 0
... ...
PD1 + 0x3FF * L 0
其中:
和PT1
:表1和表2在RAM上的初始位置 示例值:PT2
,0x00000000
等 是操作系统决定了这些价值观0x12345678
:页表条目的长度L
:表示页面存在于内存中present
--------------> 0xFFFFFFFF
--------------> PT1 + 0xFFFFF * L
Page Table 1
--------------> PT1
--------------> PT2 + 0xFFFFF * L
Page Table 2
--------------> PT2
--------------> 0x0
两个页表在RAM上的初始位置是任意的,由操作系统控制。由操作系统来确保它们不会重叠
每个进程不能直接接触任何页表,尽管它可以向操作系统发出请求,导致页表被修改,例如请求更大的堆栈或堆段
页面是4KB(12位)的块
linear physical
--------- ---------
00000 002 00001 002
00000 003 00001 003
00000 FFF 00001 FFF
00001 000 00000 000
00001 001 00000 001
00001 FFF 00000 FFF
00003 000 00003 000
FFFFF 000 00004 000
int is[1];
is[2] = 1;
| directory (10 bits) | table (10 bits) | offset (12 bits) |
RAM location physical address present
--------------- ----------------- --------
PD1 + 0 * L 0x10000 1
PD1 + 1 * L 0
PD1 + 2 * L 0x80000 1
PD1 + 3 * L 0
... ...
PD1 + 0x3FF * L 0
RAM location physical address present
--------------- ----------------- --------
PT1 + 0 * L 0x00001 1
PT1 + 1 * L 0
PT1 + 2 * L 0x0000D 1
... ...
PT1 + 0x3FF * L 0x00005 1
RAM location physical address present
--------------- ----------------- --------
PT2 + 0 * L 0x0000A 1
PT2 + 1 * L 0x0000C 1
PT2 + 2 * L 0
... ...
PT2 + 0x3FF * L 0x00003 1
----------------> 0xFFFFFFFF
----------------> PT2 + 0x3FF * L
Page Table 1
----------------> PT2
----------------> PD1 + 0x3FF * L
Page Directory 1
----------------> PD1
----------------> PT1 + 0x3FF * L
Page Table 2
----------------> PT1
----------------> 0x0
0 0 8 0 1 0 0 4
0000 0000 1000 0000 0001 0000 0000 0100
0000000010 0000000001 000000000100
0x2 0x1 0x4
linear 10 10 12 split physical
-------- --------------- ----------
00000001 000 000 001 00001001
00001001 000 001 001 page fault
003FF001 000 3FF 001 00005001
00400000 001 000 000 page fault
00800001 002 000 001 0000A001
00801008 002 001 008 0000C008
00802008 002 002 008 page fault
00B00001 003 000 000 page fault
valid linear physical
------ ------- ---------
> 0 00000 00000
0 00000 00000
0 00000 00000
0 00000 00000
valid linear physical
------ ------- ---------
1 00003 00005
> 0 00000 00000
0 00000 00000
0 00000 00000
valid linear physical
------ ------- ---------
1 00003 00005
1 00007 00009
> 0 00000 00000
0 00000 00000
valid linear physical
------ ------- ---------
> 1 00003 00005
1 00007 00009
1 00009 00001
1 0000B 00003
valid linear physical
------ ------- ---------
1 0000D 0000A
> 1 00007 00009
1 00009 00001
1 0000B 00003
linear physical
------- ---------
00000 00001
00001 00010
00010 00011
FFFFF 00000
linear physical
------- ---------
00000 00001
00001 00010
00010 00011
... (from 00011 to FFFFE)
FFFFF 00000
#define _PAGE_BIT_PRESENT 0 /* is present */
#define _PAGE_BIT_RW 1 /* writeable */
#define _PAGE_BIT_USER 2 /* userspace addressable */
#define _PAGE_BIT_PWT 3 /* page write through */
#define X86_CR0_PG_BIT 31 /* Paging */