Linux内核6.6 内存管理(4)页表映射
3.本文主要讨论arm64架构
1.概念:
页表映射:虚拟内存到物理内存转换的机制。将连续的虚拟地址空间映射到离散的物理内存页(内存隔离/保护/高效利用)
虚拟地址:进程看到的地址空间(64位系统的0x0到0xffff ffff ffff ffff)
物理地址:实际内存芯片的地址
页(page):内存管理基本单位(4KB/2MB/1GB),虚拟地址空间和物理地址空间都被划分为固定大小的页
页表(page table):存储虚拟页到物理页的映射关系
2.多级页表结构:
4级页表(普遍)地址转换过程
虚拟地址 = [PGD索引] [PUD索引] [PMD索引] [PTE索引] [页内偏移] | | | | | | v v v v v v PGD表项 ---> PUD表项 ---> PMD表项 ---> PTE表项 --->物理页号(PFN)+左移12位(4KB)后+页内偏移
—————————————————————————页表,页表项,物理地址—————————————————————
每级页表的表项(如 PGD 表项、PUD 表项等 ),核心作用是存储下一级页表的物理基地址,构成 “指引链”。比如:
- PGD 基地址:存储在 CPU 的TTBR0_EL1/TTBR1_EL1 寄存器中,指向顶级页表(PGD)的物理地址。
PGD物理地址(已经被虚拟地址转化)+L0索引 = PGD表项
- PGD 表项:存放下一级 PUD 页表的物理基地址
- PUD 表项:存放下一级 PMD 页表的物理基地址
- PMD 表项:存放下一级 PTE 页表的物理基地址
- PTE 表项:存放物理页框号(PFN)(最终映射物理地址 )
流程类似 “找地图”:PGD 表项告诉你 “PUD 页表在物理内存的 XX 地址”,PUD 表项告诉你 “PMD 页表在 XX 地址” ,直到 PTE 表项告诉你 “物理页在 XX 地址”
页表项类型 typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pud; } pud_t; typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pte; } pte_t; 页表操作函数 // 查找页表项 pgd_t *pgd_offset(struct mm_struct *mm, unsigned long addr); pud_t *pud_offset(pgd_t *pgd, unsigned long addr); pmd_t *pmd_offset(pud_t *pud, unsigned long addr); pte_t *pte_offset_map(pmd_t *pmd, unsigned long addr); // 设置页表项 static inline void set_pte(pte_t *ptep, pte_t pte);//把 “虚拟地址→物理地址的映射关系”,通过 pte_t 结构体封装后,写入页表对应的位置,完成地址映射配置。 static inline void set_pmd(pmd_t *pmdp, pmd_t pmd);
3.有关虚拟页的数据结构
3.1 vm_area_struct (VMA) 连续的虚拟地址空间及其属性
内核将进程的虚拟地址空间划分为多个VMA,每个VMA代表一个逻辑上的内存区域(.text .data stack 映射文件等)
3.2 mm_struct 进程的所有虚拟内存区域
每个进程都有一个mm_struct,通过它可以访问进程的所有虚拟内存区域和页表
3.3 page table 虚拟地址到物理地址的映射
4.内存映射的两种类型
4.1文件映射(File Mapping)
将文件内容直接映射到虚拟地址空间,读写内存相当于读写文件。
4.2匿名映射(Anonymous Mapping)
不关联具体文件,分配的内存初始化为 0(如堆、栈)。
#嵌入式##嵌入式笔面经分享##牛客在线求职答疑中心##牛客创作赏金赛#