在x86 CPU中,控制寄存器号为0。该寄存器的第16位指示“写保护”设置。如果清除该位,则CPU能够覆盖只读数据。(在页表项中配置)在内存中。如果此位置1,则CPU无法覆盖内存中的RO数据。
我很好奇的是“此位的原始目的是什么?”“为什么x86 CPU需要这个?”
从Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3A pg. 2-15报价(强调我的名字:):
WP写保护(CR0的第16位)—置位时,禁止管理员级过程写入只读页面;如果清除,则允许主管级别的过程写入只读页面(与U / S位设置无关;请参见4.1.3节和4.6节)。 此标志有助于实现诸如UNIX之类的操作系统使用的写时复制方法的创建新进程(分支)的实现。]
更新:看着wikipedia on fork():
[只要进程(父级或子级)修改了页面,就会为执行修改的那个进程(父级或子级)单独创建该页面的单独副本。
这是写时复制的核心,但是当修改由内核完成时(例如,由于syscall发生写操作时,请考虑
read()
)会出现问题。
来自4.1.3:
CR0.WP允许保护页面免受超级用户模式写入。如果CR0.WP = 0,则以超级用户模式写入允许访问具有只读访问权限的线性地址;如果CR0.WP = 1,则不是。 (用户模式禁止访问具有只读访问权限的线性地址,无论CR0.WP。)
通过设置
CR0.WP = 1
,内核将在修改只读用户页面时收到通知(带有页面错误),并且可以在继续进行页面修改之前执行写时复制操作。
WP = 1是默认值。它在内核写入只读用户(U)页时启用陷阱,因此内核可以检查它是否是COW页,否则它将必须检查它正在访问的每个内存地址,否则将通过进行更改来破坏COW对映射内存的其他进程可见。