linux 进程页表流程

在这里插入图片描述
mm_alloc_pgd() 函数会调用pgd_alloc()会为该进程分配一页(4K)的页全局目录的线性地址并保存在 task_struct->mm_struct->pgd中

具体的实现是通过__get_free_pages((gfp_mask), 0)实现的,该函数通过alloc_pages()在低端内存里( 小于896M的空间里)分配一个页描述符(struct page *page),并将该页的页描述符通过page_address()转换成虚拟地址。实际上就是通过__va(PFN_PHYS(page_to_pfn(page)))先将页描述符转换成实际物理地址((page - mem_map) << 12 )(所有的物理页描述符存放在mem_map数组里,左移12是一页4K的大小),然后再将物理地址通过__va转换成虚拟地址,也即将得到的低端物理内存地址直接加上PAGE_OFFSET即可 (unsigned long )(x)+PAGE_OFFSET

到现在可以得知进程描述符里的mm_struct->pgd是线性地址,而且属于内核空间的地址(大于0xc0000000)。

pte的映射(写时复制机制)

dup_mm()->dup_mmap 中完成中间页表pmd到页表pte的映射从而建立起页表,并将每一个pte页表,置为只读,以便激发起写时复制技术dup_mmap执行,继续复制pte页表项,使子进程的每个中间页表pmd的每个页表项pte=父进程对应的该pte,并且将该pte最后几个标志位中的只读位置1,从而完成写时复制的准备工作

cr3寄存器的加载

cr3寄存器的加载是在进程调度的时候更新的,具体如下
schedule()->context_switch()->switch_mm()->load_cr3(next->pgd)
load_cr3加载的是mm_struct->pgd,即线性地址,而实际上加裁到cr3寄存器的是实际的物理地址write_cr3(__pa(pgdir));在装载cr3寄存器时将线性地址通过__pa转换成了物理地址了,所以cr3寄存器是装的是实实在在的物理地址。
正在使用的页目录的物理地址存在cr3控制寄存器中
当要fork一个新的进程时,会先去分配一个物理页(4K)(copy_mm()->dup_mm()->mm_init()中实现)作为该进程的页目录
32位机器时 4K页里可用1024项,而页目录里的每一项指向一个页表(4K),4K的页表也只有1024项可用,而页表中的每一项又指向具体的一页,所以一个进程的理论可用的空间是1024( 页目录)x1024(页表)x4Kb(每页4K)= 4G(物理页)
在这里插入图片描述

上述说的cr3寄存器装载的是普通进程的页目录首地址,而内核线程使用的是swapper_pg_dir页目录地址

内核态访问的是线性地址空间,没有线性地址的物理内存是不能被内核访问的,因此,映射就是指将物理内存地址映射到内核线性地址上。这样内核才能访问。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值