linux内核源码分析之页表

Posted 为了维护世界和平_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux内核源码分析之页表相关的知识,希望对你有一定的参考价值。

目录

页表说明

虚拟地址转换为物理地址过程

内核中的宏以及说明


页表用来把虚拟页映射到物理页,并且存放页的保护单位,即访问权限。

页表说明

5级页表如下

1)页全局目录(Page Global Directory,PGD)

2)  页四级目录(Page 4th Directory,P4D)

3)页上册目录(Page Upper Directory,PUD)

4)页中间目录(Page Middle Directory,PMD)

5)直接页表(Page Table ,PT)

        各处理器架构可以选择使用五级,四级,三级,两级页表。同一处理器架构在页长度不同的情况下可能选择不同的页表级数。配置页表级数,内核中宏CONFIG_PGTABLE_LEVELS,一般使用默认值。

 每个进程有独立的页表,进程的mm_struct实例的成员pgd指向全局目录,前面四级的页表项存放下一级页表的起始地址,直接地址的页表项存放帧号(Page Frame Number  PFN)。

虚拟地址被分解为6部分:全局目录索引,页四级目录索引,页上层目录索引,页中间目录索引,直接页表索引和业内偏移。

虚拟地址转换为物理地址过程

查询页表,把虚拟地址映射为物理地址

1)根据全局目录的起始地址页全局目录索引得到页全局目录表项的地址,然后从页表项得到四级目录的起始地址。以此类推得到直接页表的起始地址。

2)根据直接页表的起始地址和直接页表的索引得到页表项的地址,然后得到页帧号。

3)页帧号页内偏移组合成物理地址。

内核中的宏以及说明

内核定义了各级页表索引在虚拟地址中的偏移

PAGE_SHIFT页内偏移位数
PMD_SHIFT页中间目录索引的偏移
PUD_SHIFT页上层目录索引的偏移
P4D_SHIFT页四级目录索引的偏移
PGDIR_SHIFT页全局索引的偏移

 定义了各级页表表项描述的地址空间大小

PAGE_SIZE直接页表项映射的地址空间的大小,单位页长度
PMD_SIZE 页中间目录表项映射的地址空间大小
PUD_SIZE页上层目录表项映射地址空间大小
P4D_SIZE页4级目录表项映射地址空间大小
PGDIR_SIZE全局目录表项映射地址空间大小

各级页表存放指针个数以及页的阶数

PTRS_PER_PGD全局目录的表项数据PGD_ORDER全局目录页阶
PTR_PER_P4D页四级目录的表项数量P4D_ORDER四级目录页阶
PTR_PER_PUD页上层目录的表项数量PUD_ORDER上层目录页阶
PTR_PER_PMD页中间目录的表项数量PMD_ORDER中间目录页阶
PTR_PER_PTE直接页表的表项数量PTE_ORDER直接页表阶数

typdef struct unsigned long pgd;pgd_t;

内核定义了宏和内联函数,以全局目录为例

//宏pgd_val()用来把pgd_t类型转化换成无符号整数
#define pgd_val(x) ((x).pgd)

//宏__pgd()用来把无符号长整数转化为pgd_t类型
#define __pgd(x) ((pgd_t))  (x) )

//宏pgd_index(address)用来从虚拟地址分解除页全局目录索引
#define pgd_index(address)((address)>>PGDIR_SHIFT) & (PTRS_PER_PGD - 1)

//宏pgd_offset(mm,addr)用来返回指定进程的虚拟地址对应的页全局目录表项的地址
#define pgd_offset_k(address) pgd_offset(&init_mm,address)

//内联函数pgd_none(pgd)用来判断页全局目录表项是空表项,空表项没有指向下一级

//内联函数pgd_present(pgd)用来判断页全局目录表项是否存在,即是否指向下一级页表

大多数处理器支持的最小页长度是4KB

参考链接

https://course.0voice.com/v1/course/intro?courseId=2&agentId=0


以上是关于linux内核源码分析之页表的主要内容,如果未能解决你的问题,请参考以下文章

linux kernel 内存管理-页表、TLB

linux内核源码解析03–启动代码分析之主内核页表创建

linux内核源码分析之物理内存组织结构

linux 临时页目录和页表初始化分析

Linux内核源码分析之《内存管理架构》

linux内核页表更新