#definepgd_offset(mm,addr)((mm)->pgd+pgd_index(addr))//由虚拟地址来获取用户进程的页表中相应的PGD表项 pgd_index(addr)//由虚拟地址找到PGD页表的索引 pte_index(addr)//由虚拟地址找到PT页表的索引 pte_offset_kernel(pmd,addr)//查找内核页表中对应的PT页表的表项 判断页表项的状态 #definepte_no...
addr) ((mm)->pgd +pgd_index(addr))//获得pmd表的起始地址/* to find an entry in a kernel page-table-directory */#definepgd_offset_k(addr)pgd_offset(&init_mm, addr)
因为我们是在内核空间中,内核中所有进程共享同一页表,利用pgd_offset这个函数和current->mm,就能找到页表, pgd_val(*pgd)和pgd_index(vaddr)可以帮助我们查看pgd和vaddr在页表中偏移。 重复这个过程,查询下一个分页目录的值。 看一下具体的代码 { pgd_t *pgd; //为每个目录项目创建一个变量,用于保存 p4d_t...
32bit的Linux采用三级映射:PGD-->PMD-->PTE,64bit的Linux采用四级映射:PGD-->PUD-->PMD-->PTE,多了个PUD。 缩写是PGD:Page Global Directory、PUD:Page Upper Directory、PMD:Page Middle Directory、PTE:Page Table Entry。 在ARM32 Linux采用两层映射,省略了PMD,除非在定义了CONFIG_ARM_LPAE才会使用3级映射。
每个进程有独立的页表,进程的mm_struct实例的成员pgd指向页全局目录,前面四级页表的表项存放下一级页表的起始地址,直接页表的页表项存放页帧号(PFN)。 内核也有一个页表,0号内核线程的进程描述符init_task的成员active_mm指向内存描述符init_mm,内存描述符init_mm的成员pgd指向内核的页全局目录swapper_pg_dir。
Linux:页表中PGD、PUD、PMD等概念介绍 1、PGD: Page Global Directory Linux系统中每个进程对应用户空间的pgd是不一样的,但是linux内核 的pgd是一样的。当创建一个新的进程时,都要为新进程创建一个新的页面目录PGD,并从内核的页面目录swapper_pg_dir中复制内核区间页面目录项至新建进程页面目录PGD的相应位置,具体...
pgd_ctor(mm, pgd); //关键代码,将指向内核空间的页目录项拷贝到新分配的pgd对应的项目中。 -> clone_pgd_range(pgd + KERNEL_PGD_BOUNDARY, //item points to the kernel space swapper_pg_dir + KERNEL_PGD_BOUNDARY,KERNEL_PGD_PTRS); ref. ...
context_switch// kernel/sched/core.c->switch_mm_irqs_off->switch_mm->__switch_mm->check_and_switch_context->cpu_switch_mm->cpu_do_switch_mm(virt_to_phys(pgd),mm)//arch/arm64/include/asm/mmu_context.harch/arm64/mm/proc.S158/*159* cpu_do_switch_mm(pgd_phys, tsk)160*161* Set...
pgd = pgd_offset_k(addr); /* (2) */if (CONFIG_PGTABLE_LEVELS > 3 &&!(pgd_none(*pgd) || pgd_page_paddr(*pgd) == __pa_symbol(bm_pud))) {/** We only end up here if the kernel mapping and the fixmap* share the top level pgd entry, which should only happen on* 16k/4...
pgd_t*pgd; interr=0; inti; /*2.使用pgd_offset_k宏在主内核PGD页全局目录中 *导出与该区域的初始线性地址相关的表项 */ pgd=pgd_offset_k(address); /*3.申请内核页表自旋锁*/ spin_lock(&init_mm.page_table_lock); for(i=pgd_index(address);i<= pgd_index(end-1); i++) { ...