读《Linux内核设计的艺术》时,书里使用的linux版本是0.11。内存管理的策略是task[64]:
将4GB线性空间分成互不重叠的64份,每份64MB,每个进程一份,最多只能同时开启64个进程
因此,只需要一个页目录表即可,不存在线性地址冲突。
CR3指向这个全局的页目录表,进程切换的时候也不需要修改。
但是现在的Linux似乎不是这样
读《csapp》时,里面写到,每个进程的代码段都是从0x400000开始。这跟0.11里的策略是冲突的,因为不同进程的虚拟地址有可能重叠,只有一个页目录表怎么处理这个重叠问题?
继续往后看,发现Linux已经没有页目录表了,取而代之的是每个进程都有独自的页表,CR3指向的是一级页表的基址。
每个进程的一级页表基址存储在task_struct->mm->pgd中
进程切换的时候CR3也会切换到对应进程的一级页表基址。
这么一看,硬件上用的还是CR3和MMU。但是操作系统的策略变了,反正操作系统可以修改CR3存储的基址,不管是全局使用一个页目录,还是每个进程一个页目录(页表),都是行得通的。
那么,这个策略变更是从Linux的哪个版本开始的呢