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

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

相关推荐
chlk12315 小时前
Linux文件权限完全图解:读懂 ls -l 和 chmod 755 背后的秘密
linux·操作系统
舒一笑15 小时前
Ubuntu系统安装CodeX出现问题
linux·后端
改一下配置文件16 小时前
Ubuntu24.04安装NVIDIA驱动完整指南(含Secure Boot解决方案)
linux
深紫色的三北六号1 天前
Linux 服务器磁盘扩容与目录迁移:rsync + bind mount 实现服务无感迁移(无需修改配置)
linux·扩容·服务迁移
SudosuBash1 天前
[CS:APP 3e] 关于对 第 12 章 读/写者的一点思考和题解 (作业 12.19,12.20,12.21)
linux·并发·操作系统(os)
哈基咪怎么可能是AI2 天前
为什么我就想要「线性历史 + Signed Commits」GitHub 却把我当猴耍 🤬🎙️
linux·github
十日十行2 天前
Linux和window共享文件夹
linux
木心月转码ing3 天前
WSL+Cpp开发环境配置
linux
崔小汤呀4 天前
最全的docker安装笔记,包含CentOS和Ubuntu
linux·后端
何中应4 天前
vi编辑器使用
linux·后端·操作系统