paging_init()

paging_init()负责建立仅用于kernel而用户空间不可访问的页表。

在IA-32系统的4GB虚拟地址空间总是以3:1的比例分配,用户态应用占用3G,kernel占用1G。当前系统上下文与分配的kernel的虚拟地址无关,每个进程都有自己指定的地址空间。

这样分配的原因如下:

当从用户态切换到内核态时,kernel必须嵌入到一个可靠的环境。因此分配部分地址空间仅用于kernel是很重要的。

物理页映射到内核地址空间的起始位置,因此kernel可以直接访问它们,无需复杂的页表操作。

如果物理页映射到可被用户空间进程访问的地址空间,且有多个应用运行在系统中,将导致严重的安全问题。因为每个应用都可以访问并修改其他应用在物理RAM中的内存区域。

用户空间进程的虚拟地址经常在task-switch时切换,而kernel部分总是相同的。

kernel地址空间分配如下:

地址空间的第一部分用于映射系统所有的物理页到kernel的虚拟地址空间。因为kernel地址空间起始于0xC0000000的偏移,因为每个 虚拟地址x对应到物理地址都需要做简单的线性移动。如图所示,直接映射区域从0xC0000000到high_memory。因为kernel的虚拟地址 空间仅1G,所以最大可映射1G的RAM。因此kernel无法一次映射超过896M的全部物理内存。这个值甚至小于前面提到的最大1G的限制,因为 kernel必须保留至少128M的地址空间用于其他目的。kernel经常使用两个缩写"normal"和“highmem”来区分可被直接映射的页和不可被直接映射的页。

你可能感兴趣的:(paging_init())