linux Page Table 和 TLB 操作总结

以下是 Linux 内核中与页表和 TLB 操作对应的主要 API/函数列表,结合上述操作分类:


页表(Page Table)相关 API

1. 地址转换

操作 内核 API/函数 说明
虚拟地址→物理地址 virt_to_phys()__pa() 内核虚拟地址转物理地址
物理地址→虚拟地址 phys_to_virt()__va() 物理地址转内核虚拟地址
页表遍历 pgd_offset()p4d_offset()pud_offset()pmd_offset()pte_offset_map() 多级页表各级索引获取
获取页表项 pte_t *pte = pte_offset_kernel(pmd, addr) 获取内核地址的 PTE

2. 页表项管理

操作 内核 API/函数 说明
创建页表 pgd_alloc()pud_alloc()pmd_alloc()pte_alloc() 分配各级页表结构
设置映射 set_pte_at()set_pmd()set_pud() 设置页表项内容
建立映射 remap_pfn_range()vm_insert_page()io_remap_pfn_range() 建立虚拟到物理映射
删除映射 pte_clear()pmd_clear() 清除页表项
释放页表 pgd_free()pte_free() 释放页表内存

3. 权限与状态检查

操作 内核 API/函数 说明
检查有效位 pte_present() 检查页面是否在内存中
检查权限 pte_write()pte_read()pte_exec() 检查读写执行权限
设置权限 pte_mkwrite()pte_wrprotect()pte_mkexec() 修改 PTE 权限位
访问/修改位 pte_young()pte_dirty() 检查访问/修改位
标记访问/修改 pte_mkyoung()pte_mkdirty() 设置访问/修改位

4. 缺页处理

操作 内核 API/函数 说明
缺页异常入口 handle_mm_fault() 缺页异常主要处理函数
调页 do_swap_page()do_anonymous_page()do_wp_page() 不同类型缺页处理
页面分配 alloc_page()__get_free_page() 分配物理页面

5. 页表切换

操作 内核 API/函数 说明
切换页表 switch_mm() 进程上下文切换时切换页表
设置页表基址 load_cr3()(x86) 加载新页表基址到 CR3

TLB 相关 API

1. TLB 刷新(一致性维护)

操作 内核 API/函数 说明
单页刷新 flush_tlb_page()flush_tlb_mm_range() 使指定虚拟地址的 TLB 项无效
进程空间刷新 flush_tlb_mm() 使指定进程所有 TLB 项无效
全局刷新 flush_tlb_all() 使所有 TLB 项无效(全系统)
跨CPU刷新 flush_tlb_kernel_range() 刷新内核地址范围的 TLB(所有CPU)

2. TLB 刷新优化

操作 内核 API/函数 说明
延迟刷新 tlb_gather_mmu()tlb_finish_mmu() 批量 TLB 刷新优化
范围刷新 flush_tlb_range() 刷新指定地址范围的 TLB

3. 架构相关 TLB 操作

操作 内核 API/函数 说明
x86 TLB 刷新 __flush_tlb_one()__flush_tlb_all() x86 架构特定 TLB 操作
ARM TLB 操作 flush_tlb_all()local_flush_tlb_all() ARM 架构实现
TLB 射击 smp_call_function() + TLB 刷新 多核间 TLB 一致性维护

内存映射相关 API(综合操作)

操作 内核 API/函数 说明
建立内存映射 mmap() 系统调用 → do_mmap() 用户空间内存映射
取消映射 munmap()do_munmap() 解除内存映射
改变保护 mprotect()do_mprotect_pkey() 修改页面保护权限
同步映射 msync()do_msync() 同步内存与文件内容

关键数据结构

数据结构 说明
struct mm_struct 进程内存描述符,包含页表基址等信息
struct vm_area_struct 虚拟内存区域描述符
pgd_tp4d_tpud_tpmd_tpte_t 各级页表项类型
struct page 物理页面描述符

使用示例

c 复制代码
/* 建立页表映射示例 */
pte_t *pte;
spinlock_t *ptl;
pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
if (pte_present(*pte)) {
    /* 页面存在 */
    pte_mkdirty(*pte);  /* 标记为脏 */
    pte_mkyoung(*pte);  /* 标记为访问过 */
}
set_pte_at(mm, addr, pte, pte_mkwrite(pte_mkdirty(pte_mkyoung(*pte))));
pte_unmap_unlock(pte, ptl);

/* TLB 刷新示例 */
flush_tlb_page(vma, addr);  /* 刷新单个页面 */

总结表

操作类别 页表 API 示例 TLB API 示例
地址转换 virt_to_phys()pte_offset_map() -
映射管理 set_pte_at()pte_clear() -
权限检查 pte_write()pte_present() -
缺页处理 handle_mm_fault()do_swap_page() -
一致性维护 - flush_tlb_page()flush_tlb_all()
批量优化 - tlb_gather_mmu()tlb_finish_mmu()
上下文切换 switch_mm() 通常包含在 switch_mm()

这些 API 主要位于以下内核文件中:

  • include/asm-generic/pgtable.h
  • arch/x86/include/asm/pgtable.h
  • arch/x86/mm/tlb.c
  • mm/memory.c
  • mm/mmap.c

实际使用中需注意架构差异和内核版本变化。

相关推荐
A小辣椒1 天前
TShark:Wireshark CLI 功能
linux
A小辣椒1 天前
TShark:基础知识
linux
AlfredZhao1 天前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao2 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠3 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush43 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5203 天前
Linux 11 动态监控指令top
linux
不会C语言的男孩3 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言