当前位置: 首页 > backend >正文

Linux x86_64架构下的四级分页机制详解

目录

一、x86_64分页概述

二、四级分页结构

三、地址转换过程

四、各级页表详解

1. PGD (Page Global Directory)

2. PUD (Page Upper Directory)

3. PMD (Page Middle Directory)

4. PT (Page Table)

五、页表条目结构

六、大页面支持

七、实际寻址示例

八、Linux内核中的实现

九、性能优化


一、x86_64分页概述

        在x86_64架构下,Linux使用四级分页机制来管理虚拟内存到物理内存的映射。这种分级结构允许操作系统高效地管理巨大的地址空间(理论上256TB),同时保持内存使用的灵活性。

二、四级分页结构

        x86_64架构下的四级分页包括以下层级:

  1. PGD (Page Global Directory) - 页全局目录 
  2. PUD (Page Upper Directory) - 页上层目录
  3. PMD (Page Middle Directory) - 页中间目录
  4. PT (Page Table) - 页表

三、地址转换过程

        一个64位的虚拟地址在分页过程中被划分为多个部分:

63        48 47    39 38    30 29    21 20    12 11       0
+-----------+--------+--------+--------+--------+-----------+
| 符号扩展位 | PGD索引 | PUD索引 | PMD索引 | PT索引 | 页内偏移 |
+-----------+--------+--------+--------+--------+-----------+
  1. CR3寄存器:存储当前进程的PGD物理地址  
  2. 地址转换步骤: 
  • 从CR3获取PGD基址
  • 用PGD索引找到PUD条目
  • 用PUD索引找到PMD条目
  • 用PMD索引找到PT条目
  • 用PT索引找到最终的物理页框
  • 结合页内偏移得到最终物理地址

四、各级页表详解

1. PGD (Page Global Directory)

  • 每个进程有独立的PGD

  • 存储在mm_struct->pgd

  • 上下文切换时会将其物理地址加载到CR3寄存器

  • 通常占用9位索引(512个条目)

2. PUD (Page Upper Directory)

  • 在x86_64中,PUD通常只使用一个条目

  • 主要用于兼容性,为未来扩展预留

  • 同样占用9位索引

3. PMD (Page Middle Directory)

  • 中间级别的页目录

  • 可以指向页表或更大的页面(如2MB大页)

  • 占用9位索引

4. PT (Page Table)

  • 最终级别的页表

  • 直接指向物理页框

  • 占用9位索引(512个条目)

  • 每个条目映射一个4KB页面

五、页表条目结构

        每个页表条目(PTE)是64位(8字节),包含以下重要字段:

63      62      61      52 51      32 31      12 11     9 8 7 6 5 4 3 2 1 0
+-------+-------+--------+-----------+-----------+-------++-+-+-+-+-+-+-+-+
| NX    |       |        | 保留(软件) | 物理页基址 | Avail |D|A| | | |U|W|P|
+-------+-------+--------+-----------+-----------+-------++-+-+-+-+-+-+-+-+

         关键标志位:

  • P (Present):页面是否在物理内存中

  • RW (Read/Write):可写权限

  • US (User/Supervisor):用户空间是否可访问

  • PWT/PCD:缓存控制

  • A (Accessed):页面是否被访问过

  • D (Dirty):页面是否被修改过

  • NX (No Execute):禁止执行位(安全特性)

六、大页面支持

        x86_64支持多种页面大小:

  • 4KB:标准页面,使用全部四级页表

  • 2MB:大页面,绕过PT级别,直接在PMD中映射

  • 1GB:巨大页面,绕过PMD和PT级别,直接在PUD中映射

        大页面减少了TLB缺失,提高了内存访问性能。

七、实际寻址示例

        假设48位虚拟地址0xFFFF800012345678的转换过程:

1.  符号扩展为64位:0xFFFFFFFF800012345678  

2.  分解各部分:

  • PGD索引:0x100 (第257项)
  • PUD索引:0x000
  • PMD索引:0x001
  • PT索引:0x234
  • 偏移:0x5678

3.  依次查询各级页表最终得到物理页框基址,加上偏移得到物理地址

八、Linux内核中的实现

关键数据结构:

// 页表条目
typedef struct { unsigned long pte; } pte_t;
// PMD条目
typedef struct { unsigned long pmd; } pmd_t;
// PUD条目
typedef struct { unsigned long pud; } pud_t;
// PGD条目
typedef struct { unsigned long pgd; } pgd_t;

关键宏和函数:

  • pgd_offset(mm, addr):获取PGD条目

  • pud_offset(pgd, addr):获取PUD条目

  • pmd_offset(pud, addr):获取PMD条目

  • pte_offset_map(pmd, addr):获取PTE条目

九、性能优化

  1. TLB (Translation Lookaside Buffer):缓存最近使用的地址转换
  2. PCID (Process Context ID):减少TLB刷新
  3. 延迟分配:实际访问时才分配物理页
  4. 反向映射:高效的反向查找(从物理页到PTE)

        四级分页机制是x86_64架构高效管理大内存的关键,通过分级结构平衡了内存占用和查找效率。

 

http://www.xdnf.cn/news/13841.html

相关文章:

  • Cordova移动应用对云端服务器数据库的跨域访问
  • 图像处理与机器学习项目:特征提取、PCA与分类器评估
  • AI基础知识(07):基于 PyTorch 的手写体识别案例手册
  • 一篇文章理解js闭包和作用于原理
  • 【消息队列】——如何使用Actor模型解决并发问题
  • 基于springboot视频及游戏管理系统+源码+文档
  • Python图像处理基础(六)
  • 域名证书自动更新-acme通用版
  • 网络编程之Modbus与HTTP
  • MySQL中InnoDB存储引擎底层原理与MySQL日志机制深入解析
  • 【在线五子棋对战】五、前端扫盲:html css javascript ajax jquery websocket
  • 应用案例丨一键测量300+工件,QM系列闪测仪批量检测
  • 多模态大语言模型arxiv论文略读(119)
  • 爱普生FC-135R晶振在广域网LoRa设备中的应用
  • 达梦数据库中无效触发器的排查与解决方案指南
  • Java Lambda 表达式与 Stream API 全解析:从基础到进阶
  • 短剧小程序开发:开启碎片化娱乐新视界
  • 第 4 篇:线性回归——机器学习“开山第一斧”,用一条直线洞见AI本质
  • 机器学习-黑马笔记
  • Redis缓存三大难题:穿透、击穿、雪崩
  • 名称 深度学习(监督学习) Iteration 一次 mini-batch 前向+反向传播更新 Epoch 所有数据集训练一遍。这两个概念不一样吗?
  • openEuler 虚拟机中 Shell 脚本实现自动化备份与清理实践
  • (十四)上市企业(协会)实施IPD成功案例分享之——美国建筑师协会AIA
  • MS1824+MS7210 AV/S-Video/VGA/YPbPr/RGB888/BT601、656/BT1120转HD转换器
  • tvm开源程序是适用于 CPU、GPU 和专用加速器的开放式深度学习编译器堆栈
  • window 显示驱动开发-处理视频帧
  • Lua 的闭包(closure)特性
  • 每日Prompt:宫崎骏风格插画
  • mapbox高阶,使用mbview发布mbtiles数据为矢量切片服务,并加载
  • 《TCP/IP协议卷1》 ARPICMP协议