【发布时间】:2013-12-31 12:54:55
【问题描述】:
在 32 位 Linux(或 windows 等)中,用户进程无法访问 内核地址空间。说 0xC0100000 (在 3:1 拆分中,例如 linux)或 0x80E00000(1:1分割如windows)。
我知道用户应用程序中的以下代码会引发分段错误。
int* a = 0xC0100000;
int b = *a;
但是,我不能 100% 确定实际原因。 我假设如果我们尝试执行上述代码,MMU 将引发 segfault,因为虚拟地址 0xC0100000 的相应页表条目具有管理位标志。 这是 100% 正确的吗?如果正确,操作系统如何阻止进程通过 TLB 缓存访问内核虚拟地址?
我也认为使用分段可以实现相同的限制。 即如果 GDT 的 DS、CS、SS ... 条目的地址限制为 0xC0000000。无论页表设置如何,访问 0xC0100000 都会从分段过程中失败。 如果我错了,请纠正我。
一些建议会很好。 提前谢谢你。
【问题讨论】:
-
为什么 TLB 会影响这个?
-
因为如果 TLB 命中,MMU 将不会遍历页表,这意味着它无法检查页表条目标志。
-
@daehee TLB 是页表条目的缓存,它包含相同的标志。
-
MMU 没有“segfault”,它发送一个处理器异常。该异常触发了一个由内核处理的中断,稍后可以向应用程序发送
SIGSEGV信号。 -
@daehee:不,虽然 TLB 命中不会导致页面遍历是正确的,但权限也会被缓存。
标签: linux segmentation-fault kernel paging