虚拟内存分为两部分。传统上,0~3GB 用于用户空间,3GB~4GB 用于内核空间。
我的问题:
用户空间的线程可以访问内核空间的内存吗?
对于 ARM 数据表,访问属性由域访问控制寄存器负责。但是在内核源代码中,用户空间虚拟内存的页表项中的域值与内核空间的页表项相同。
虚拟内存分为两部分。传统上,0~3GB 用于用户空间,3GB~4GB 用于内核空间。
我的问题:
用户空间的线程可以访问内核空间的内存吗?
对于 ARM 数据表,访问属性由域访问控制寄存器负责。但是在内核源代码中,用户空间虚拟内存的页表项中的域值与内核空间的页表项相同。
事实上,您的应用程序可能会访问页面 0xFFFF0000,因为它包含 swi-handler 和其他几个用户空间助手。所以不,3/1 分割并不神奇,内核非常容易管理。
通常内核会将所有超过 3GB 的内存设置为只能由内核域本身访问。如果驱动程序需要在用户和内核空间之间共享内存,它通常会提供一个 mmap 接口,然后创建一个别名映射,因此您有两个虚拟地址用于同一个物理地址。这只适用于 VIPT-Cache 系统或大量仔细的显式缓存刷新。如果您不希望这样,您可以破解内核以使用户空间可以访问 3G 拆分之上的一块内存。但随后所有用户空间应用程序将共享此内存。我已经为 armv5 系统上的特殊应用程序做过一次。
用户空间代码获取内核内存?唯一允许这样做的内核是 DOS 及其古老的朋友。但回到问题上来,看看这个示例 C 代码:
char c=42;
*c=42;
我们取一个字节 (a char
) 并为其分配数值 42。然后我们取消引用这个非指针,它可能会尝试访问虚拟内存的第 42 个字节,这几乎绝对不是你的内存,并且,为了这个例子,内核内存。猜猜当你运行它时会发生什么(如果你设法将编译器放在枪口下):
Segmentation fault
Linux 像任何现代操作系统一样具有内存保护。如果您尝试访问另一个进程的内存,您的进程将在它可以做任何事情之前被终止(虽然我不太确定调试器会发生其他事情)。即使该内存是另一个 Userland 进程的内存,您仍然会被终止。我几乎可以肯定root
程序无法访问其他程序内存或内核内存。访问内核内存的唯一方法是成为内核的一部分,或者间接通过内核的合作。