如果我们有一个 32 位 CPU,它可以有 4GB 的虚拟地址空间。前 3GB(0-3GB)用于用户空间虚拟地址,其余 1GB(3GB-4GB)用于内核虚拟地址。但是正如我在很多文章中看到的,甚至在 LDD 书中,都说内核虚拟地址直接映射到具有固定偏移量的物理内存。即0xc0000001内核虚拟地址映射到0x1 RAM。实际地址。而且,为内核映射的物理内存不能被换出。
我的问题是,如果所有 RAM 都交给内核,用户空间如何访问物理 RAM。
提前感谢您的回答!
如果我们有一个 32 位 CPU,它可以有 4GB 的虚拟地址空间。前 3GB(0-3GB)用于用户空间虚拟地址,其余 1GB(3GB-4GB)用于内核虚拟地址。但是正如我在很多文章中看到的,甚至在 LDD 书中,都说内核虚拟地址直接映射到具有固定偏移量的物理内存。即0xc0000001内核虚拟地址映射到0x1 RAM。实际地址。而且,为内核映射的物理内存不能被换出。
我的问题是,如果所有 RAM 都交给内核,用户空间如何访问物理 RAM。
提前感谢您的回答!
如果所有内存都直接映射到内核虚拟地址,用户虚拟地址如何访问物理内存
这个问题没有意义,因为它的前提不正确。
所有物理内存都没有映射到内核(除非物理 RAM 真的那么小而内核映像那么大)。
内核只映射实际需要保存其代码和数据的物理内存页。
未使用的内存页面进入空闲内存池。
我的问题是,如果所有 RAM 都交给内核,用户空间如何访问物理 RAM。
真实的是“所有的 RAM 都给了内核”,以便内核可以管理它。
每当创建进程、加载其代码并请求内存缓冲区时,内核将使用页表映射将物理内存“分配”给该进程。
当进程终止(或其页面被换出)时,物理内存“恢复”回内核。
用户空间应该只知道虚拟内存。它只能访问其虚拟地址空间中已经映射到虚拟内存的物理内存。
从虚拟地址到物理地址的转换以及对 RAM 位置的访问由 CPU 和 MMU 在指令执行期间处理。
因此,假设我们的 RAM 为 1G,系统中只有 1 个用户空间进程正在运行。假设用户空间进程占用了 8KB ( 0 - 0x1FFF ) 的内存,所以只要系统中有这个进程,这个范围的内存将不可用,如果内核进程尝试使用 kmalloc 获取内存,它只能从该地区获取:0x00001FFF - 0x3FFFFFFF)?我的理解正确吗?
不,你的理解是错误的。
内存是以页为单位分配的,不保证连续的虚拟页映射到连续的物理页。
因此,您不能假设将为用户进程映射哪些物理内存页面
虚拟到物理内存的映射也不是永久的。
虚拟内存页面的内容可以在不使用时换出,然后该物理内存可以被另一个进程或内核使用。
该进程不拥有任何物理内存,并且仅因为它已(临时)映射到该进程的虚拟页面而使用物理内存页面。
kmalloc()分配一块(内核)虚拟内存(将用物理内存备份)。没有用于分配物理内存块的内核函数。
注意,只有虚拟地址空间分为用户空间和内核空间。物理内存没有这样的划分。