gpt4 book ai didi

assembly - 是否可以将进程映射到内存而不映射内核?

转载 作者:行者123 更新时间:2023-12-02 21:56:03 24 4
gpt4 key购买 nike

OSDev wiki说:

It is traditional and generally good to have your kernel mapped in every user process



为什么会这样?进程不能单独映射到内存吗?映射内核有什么好处,那不会浪费空间吗?

另外,是否可以从用户空间访问内核空间,我为什么要这样做?

最佳答案

It is traditional and generally good to have your kernel mapped in every user process



因此,当您进行系统调用时,内核不必更改页表来访问它自己的内存。始终映射所有物理内存使得 read 更便宜例如,从页面缓存中的任何位置复制内容的系统调用。

GDT 和 IDT 基地址是虚拟的 ( lidt/ lgdt ) 所以中断处理要求至少包含 IDT 的页面及其指向的中断处理程序代码在用户空间执行时被映射。

但作为对英特尔 CPU 崩溃的缓解措施,其中 user-space speculative reads can bypass the user/supervisor page-table permission bit ,Linux 确实在用户空间执行时取消了大部分内核的映射。它需要保持一个“trampoline”映射,在跳转到常规入口点之前交换页表以重新映射正确的内核,以便中断处理程序和系统调用可以工作。

is it possible to access the kernel space from the user space and why would I do that?



通常内核会禁用它。页表条目有一个 user/supervisor bit它控制在非内核模式下是否可以使用它(我认为是环 3)。因此,内核可以保留其内存映射,同时仍然保护它免受用户空间的读/写。 (另见 this for a diagram of nesting of page directories。)

CPU 有一个性能特性来支持这个用例:每个 PTE 中有一个“全局”位(如果设置)意味着即使 CR3 更改(即跨上下文切换,当内核安装时),CPU 也可以将其缓存在 TLB 中一个新的页表)。内核为它包含在每个进程中的内核映射设置了这个。

顺便说一句,这些内核映射的表可能只有一个物理副本,每个不同的用户空间页表树的顶级页映射级别 4 表 (PML4) 仅指向相同的内核 PDPTE 结构(大多数/所有这些实际上都是 1GiB 大页映射,而不是指向更深层次条目的指针)。请参阅上面链接的图表。

实际上内核允许用户空间读取(和执行)少量内存:内核映射几个 4k 页 called the VDSO area进入每个进程的地址空间(在虚拟内存的最顶部)。

对于一些简单但常见的系统调用,如 gettimeofday()getpid() , 用户空间可以 call这些页面中的函数(例如运行 rdtsc 并通过内核导出的常量缩放结果)而不是使用 syscall进入内核模式并在那里做同样的事情。这可能为现代 x86 CPU 上内核模式的往返节省了 50 到 100 个时钟周期,并且在分派(dispatch)到正确的系统调用之前不需要在内核中保存/恢复所有内容。

Is it possible to map a process into memory without mapping the kernel?



对于 64 位内核上的 32 位进程,整个 4GiB 虚拟地址空间都可用于用户空间。 (3 个左右的 4k VDSO 页除外。)

否则(当用户空间虚拟地址与内核空间虚拟地址一样宽时)Linux 使用上半部分进行所有物理内存的内核映射(在 x86 上有 1G 大页)。

i386 Linux 有一个配置选项可以使分割 1:3,IIRC,进一步限制内核,但允许更多的虚拟地址空间用于用户空间进程。 IDK,如果这对于其他体系结构上的 32 位内核很常见,或者仅适用于 x86。

wouldn't that be a waste of space?



它占用了一些虚拟地址空间,但您应该拥有比物理内存更多的虚拟地址空间。如果不这样做,则必须更频繁地支付重新映射内存的速度成本。

这就是为什么我们有 x86-64,所以虚拟地址空间很大。 48 位是 256 TiB,所以一半是 128 TiB 的地址空间。如果有必要/有用, future 的 CPU 可以实现对更宽虚拟地址的硬件支持。 ( The page table format supports up to 52 bit physical addresses. )。对于提供比 DRAM 更高密度的内存映射存储的非 volatile DIMM,这可能会成为更多问题,并且是使用大量两种地址空间的原因。

如果在单个进程中需要超过 2GiB 的虚拟地址空间,请使用 64 位系统。 (或者,如果您需要无数个进程/线程,请至少使用 64 位内核。带有 PAE 的 32 位内核有时会遇到内存分配问题。请参阅一些 https://serverfault.com/ 问题。)

有人 reposted on their blog some of Linus Torvalds' comments about PAE (Physical Address Extensions)这允许在仅 32 位的 x86 系统上拥有超过 4GB 的物理内存。总结:糟糕,即使有很好的内核端实现,它也绝对比 64 位内核慢。除了对英特尔工程师的更有趣的侮辱,他们认为这是一个好主意,可以解决 32 位操作系统的问题。

关于assembly - 是否可以将进程映射到内存而不映射内核?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46847708/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com