在32位Linux(或Windows,无论如何)中,用户进程无法访问 内核地址空间。比如说0xC0100000(以3:1分割,如linux)或者 0x80E00000(1:1分割,如窗口)。
我知道用户应用程序中的以下代码会引发分段错误。
int* a = 0xC0100000;
int b = *a;
然而,我并非100%确定实际原因。
我假设如果我们尝试执行上面的代码,MMU将引发段错误,因为虚拟地址0xC0100000的相应页表项具有超级用户位标志。
这是100%正确吗?如果这是正确的,OS如何阻止进程通过TLB缓存访问内核虚拟地址?
我还认为使用细分可以实现相同的限制。 即,如果GDT的DS,CS,SS ......条目的地址限制为0xC0000000。无论页面表设置如何,访问0xC0100000都将从分段过程中失败。 如果我错了,请帮我解决。
一些建议会很好。 提前谢谢你。
答案 0 :(得分:1)
重要的只是address space(或用户模式)中应用程序看到的user space。内核地址空间对应用程序不可见(仅对内核可见,例如在执行system calls时)。
当执行从用户模式切换到内核模式时(例如通过系统调用或中断),MMU更改状态,以访问内核页面。详细信息是特定于处理器的(在x86和ARM上不同),根据定义,应用程序代码不可见。请参阅page fault上的wikipage。