关于用户进程页表和内核页表

普通用户进程的页表也是存在内核空间的。这很容易理解,毕竟页表没有VMA来对应。在应用进程创建的时候,task_struct->m_struct描述内存信息,mm->gpd指定页表基地址。页表的分配是通过调用内核伙伴算法接口分配到物理内存,内核在启动阶段已经创建了内核页表,

用户进程的页表可以分为两个部分,其指定了不仅有0-3GB(传统32位系统)的用户空间映射(也可能还没建立映射),还有3-4GB的内核空间页。而3-4GB的内核空间页表是内核之前就已经创建好的,用户进程页表会复制内核页表。所以我们说,所有的用户进程共享内核页表。

用户进程在通过中断或者系统调用进入内核之后,MMU页表基地址依旧是当前进程的页表基地址,只不过在内核态可以访问所有的地址空间(0-4GB),当然这时候在内核态如果访问低地址(0-3GB)内存的话,就是访问到了当前进程的用户地址空间。因此使用copy_from_user的时候,用户空间地址参数在内核是可以访问的,因为此时内核可以访问该进程的用户空间页表。copy_to_user也一样。


在vmalloc区发生page fault时,将“内核页表”同步到“进程页表”中。这部分区域对应的线性地址在内核使用vmalloc分配内存时,其实就已经分配了相应的物理内存,并做了相应的映射,建立了相应的页表项,但相关页表项仅写入了“内核页表”,并没有实时更新到“进程页表中”,内核在这里使用了“延迟更新”的策略,将“进程页表”真正更新推迟到第一次访问相关线性地址,发生page fault时,此时在page fault的处理流程中进行“进程页表”的更新。

 

以上个人理解,如有偏差,欢迎指正。

 

你可能感兴趣的:(linux内核)