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)
#define pgd_page(pgd) ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK)) pte_offset_kernel():输入一个PMD(找到页框地址)和一个线性地址(找到页内偏移): #define pte_offset_kernel(pmd, address) ((pte_t *) pmd_page_kernel(*(pmd)) + pte_index(address)) #define pmd_page_kernel(pmd)...
每个进程有独立的页表,进程的mm_struct实例的成员pgd指向页全局目录,前面四级页表的表项存放下一级页表的起始地址,直接页表的页表项存放页帧号(PFN)。 内核也有一个页表,0号内核线程的进程描述符init_task的成员active_mm指向内存描述符init_mm,内存描述符init_mm的成员pgd指向内核的页全局目录swapper_pg_dir。 1.2...
Page Middle Directory (PMD):类似于PGD,但粒度更小。通常用于管理特定区域内的虚拟内存。 Inverted Page Table (IPT):与传统页表不同,IPT根据物理地址索引每个页面对应的虚拟地址和进程信息。它可以减少页表占用的内存,并提高查找效率。 Translation Lookaside Buffer (TLB):高速缓存,位于CPU芯片上,加速虚拟地址到物理...
三、create_pgd_entry 从字面上看,create_pgd_entry似乎是用来在PGD中创建一个描述符,但是,实际上该函数不仅仅创建PGD中的描述符,如果需要下一级的translation table,例如PUD、PMD,也需要同时建立,最终的要求是能够完成所有中间level的translation table的建立(其实每个table中都是只建立了一个描述符),仅仅留下PTE,...
Linux分别采用pgd_t、pmd_t、pud_t和pte_t四种数据结构来表示页全局目录项、页上级目录项、页中间目录项和页表项。这四种 数据结构本质上都是无符号长整型unsigned long Linux为了更严格数据类型检查,将无符号长整型unsigned long分别封装成四种不同的页表项。如果不采用这种方法,那么一个无符号长整型数据可以传入任...
LinuxKernel分页为了支持不同的CPU体系架构,设计了五级分页模型,如下图所示。五级分页模型是为了兼容X86-64体系架构中的5-Level Paging分页模式,见第二节。 五级分页每级命名分别为页全局目录(PGD)、页4级目录(P4D)、页上级目录(PUD)、页中间目录(PMD)、页表(PTE)。对应的相关宏定义命名如下: ...
这个是没有问题的。mm->pgd = pgd_alloc(mm);mm->pgd的确是虚拟地址,但pgd表里存放的pte表地址,...
BOUNDARY, KERNEL_PGD_PTRS); // 将内核顶级页表起始地址转换为物理地址,并加载到 cr3 寄存...
task_struct 中的 mm_struct 对象用于管理该进程(或者线程共享的)页表。准确地说,mm_struct 中的 pgd 指针指向着该进程的页全局目录。 普通进程的页全局目录 普通进程的页全局目录中,第一部分表项映射的线性地址为 0-3GB 部分,剩余部分存放的是主内核页全局目录(后面会提到)中的所有表项。