在 linux x86-64 模式下分析内存映射流程
前言
在上一篇中我们分析了 linux 在 x86-32 模式下的虚拟内存映射流程,本章主要继续分析 linux 在 x86-64 模式下的虚拟内存映射流程。
讨论的平台是 x86-64, 也可以称为 AMD64, IA-32e, 是现在广泛使用的 64 位架构,可以向前兼容 16位和 32 位的 x86. 另外一种独立的 64 位架构 IA-64与现有架构不同而且貌似发展不好,一般是接触不到的,我们平常讨论的 64 位基本就是指 x86-64.
现在的 CPU 基本都是支持 64 位的,根据处理器强大的兼容性,我们可以配置为 long mode 和 legacy mode, 根据安装的操作系统的模式可以使用不同的模式。

从 wikipedia 的截图可以看出, 我们下面要测试的是 Operating mode = Long mode, Operating sub-mode = 64-bit mode 下的虚拟内存映射流程。
映射流程简述
分段的存在更多就是为了兼容性,所以在 x86-64 下的 64位程序该功能近似于 bypass。处理器默认 CS, DS, ES, SS的段基址为 0,所以我们下面就不讨论逻辑地址到线性地址的转换了,因为基址为0,经过运算后线性地址和逻辑地址是一样的,和上一章的扁平模式一样。
分页过程会将 48-bit 的线性地址转换为 52-bit 的物理地址, 可以看出虽然是 64bit 的操作系统但在处理器层面并没有提供 2^64 大小的访问范围。48-bit 线性地址可以有以下 3 种映射分配.
4-KByte 页面

2-MByte 页面

1-GByte 页面

我们暂时还不知道 linux 使用哪种分页,但是知道了每种模式下各个寄存器和page structure entry的格式,可以下面慢慢分析。
格式

验证方案
本文整个流程参考了网上的另一篇文章,我会在文章末尾列出链接。
整个验证流程和上一篇在 x86-32 下的测试流程一样,这里就不说明了。
验证过程
编译加载
编译文件,加载 sys_reg.ko, phy_mem.ko 模块
运行 running-prog
运行后可以得到以下输出:

可以看到变量 a, 这就是我们要寻找物理地址的变量,我们给变量 a 赋了个特殊值方便确认。由于我的操作系统和 running-prog 都是64位的,所以对 a 的地址翻译是遵循 x86-64 下的机制的。a 的逻辑地址已经打印出来,而且也就是 a 的线性地址,我们先将 48bit 的线性地址分段.

PML4
控制寄存器 CR3 存储的是 PML4 的基址, bits 47~39 为 PML4E 的序号,对应的 PML4E 地址为:
0x275A1000 + 0 * 8 = 0x275A1000

PML4E 的值为 0x275DA067.
PDPT
PDPT 的基址为 0x275DA000, bits 38~30 为 PDPTE 序号,计算出的 PDPTE 地址为:
0x275DA000 + 0 * 8 = 0x275DA000

PDPTE 的值为 0x623A4067, bit7 = 0 说明指向的是 page directory.
PD
PD 的基址为 0x623A4000, bits 29~21 为 PDE 的序号,计算出 PDE 的地址为:
0x623A4000 + 3 * 8 = 0x623A4018

PDE 的值为 0x692BB067, bit7 = 0 说明指向的是 page table.
PT
PT 的基址为 0x692BB000, bits 20 ~12 为 PTE 的序号, 计算出 PTE 的地址为:
0x692BB000 + 1 * 8 = 0x692BB008

PTE 的值为 0x800000004AD6F867.
page frame
page frame 的基址为 0x4AD6F000, bits 11~0 为在 page frame内的偏移,计算出变量的物理地址为:
0x4AD6F000 + 120 = 0x4AD6F078.

熟悉的 0xA5A5AA550000FFFF, 说明我们找到了变量 a 的实际物理地址。
结束
感谢 Linux内核在x86_64 CPU中地址映射 一文,我的整个流程参考了原作者的文档和代码, 再次感谢原作者的分享。
下面是源代码链接.
study-linux-vm-64bit
在 linux x86-64 模式下分析内存映射流程的更多相关文章
- 在 linux x86-32 模式下分析内存映射流程
前言 虚拟内存机制已经成为了现代操作系统所不可缺少的一部分, 不仅可以为每个程序提供独立的地址空间保证安全性,更可以通过和磁盘的内存交换来提高内存的使用效率.虚拟内存管理作为linux 上的重要组成部 ...
- ARC模式下的内存泄露问题
ARC模式下的内存泄露问题 iOS提供的ARC 功能很大程度上简化了编程,让内存管理变得越来越简单,但是ARC并不是说不会发生内存泄露,使用不当照样会发生. 以下列举两种内存泄露情况: 死循环造成的内 ...
- 【转载】linux内核笔记之高端内存映射
原文:linux内核笔记之高端内存映射 在32位的系统上,内核使用第3GB~第4GB的线性地址空间,共1GB大小.内核将其中的前896MB与物理内存的0~896MB进行直接映射,即线性映射,将剩余的1 ...
- 鸿蒙内核源码分析(内存映射篇) | 虚拟内存虚在哪里 | 百篇博客分析OpenHarmony源码 | v15.03
百篇博客系列篇.本篇为: v15.xx 鸿蒙内核源码分析(内存映射篇) | 虚拟内存虚在哪里 | 51.c.h .o 内存管理相关篇为: v11.xx 鸿蒙内核源码分析(内存分配篇) | 内存有哪些分 ...
- windows游戏编程X86 32位保护模式下的内存管理概述(二)
本系列文章由jadeshu编写,转载请注明出处.http://blog.csdn.net/jadeshu/article/details/22448323 作者:jadeshu 邮箱: jades ...
- Asp.Net运行于32/64模式下的性能差异
项目使用的是Oracle数据库,.Net使用Odac对数据库进行访问.在官方下载Odac时会让你选择是下载32位的还是64位的.这会直接影响到网站的运行模式.目前我们使用的是32位的,那么布署时,需要 ...
- 【Linux】NAT模式下关于主机ping不通虚拟机的问题
今天打开虚拟机,然后用Xshell远程连接,发现连接不上.按照以下顺序检查了一遍. 1.虚拟机网络连接采用的是NAT模式 2.虚拟机IP采用的是自动获取. IP:192.168.191.130 子 ...
- Linux命令行模式下安装VMware Tools详细步骤
在Linux命令行模式安装VMware Tools 方法/步骤1: 首先启动CentOS 7,在VMware中点击上方"VM",点击"Install VMware Too ...
- linux命令行模式下对FTP服务器进行文件上传下载
参考源:点击这里查看 1. 连接ftp服务器 格式:ftp [hostname| ip-address]a)在linux命令行下输入: ftp 192.168.1.1 b)服务器询问你用户名和密码 ...
随机推荐
- Makefile中指示符“include”、“-include”和“sinclude”的区别
转:http://www.cnblogs.com/xmphoenix/archive/2012/02/22/2363335.html 指示符“include”.“-include”和“sinclude ...
- 关于androidManifest.xml的概叙以及intent-filter的详细分析
AndroidManifest.xml配置文件对于Android应用开发来说是比较细但又很重要的基础知识,本文旨在总结该配置文件中常用到的几个属性,以便日后查阅,至于那些比较细的属性,主要是平时开发比 ...
- windows10上安装 .NET Framework 3.5
在安装一些软件时,需要 .NET Framework3.5.按照windows给的提示下载不了.在官方网站上给了解决方案: 运行 DISM 工具 从屏幕右边缘向中间轻扫,然后点击“搜索”.(如果使用的 ...
- solrj-solr Guide 4.7
solrj是一个很容易使java应用程序和solr进行交互的一个API,solrj隐藏了很多连接Solr的细节,允许你的应用程序使用简单的高级方法和solr互动交流. solrj的核心就是 org.a ...
- TCP/IP协议原理与应用笔记27:网际协议(IP)之 选项(Options)
1. 选项(Options) (1)作用:网络测试或者调试,可选 (2)格式:0~40 bytes 2. 选项类型:
- windws 安装jdk
(1) 到官网下载好jdk:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html (2 ...
- Rolls.java (page44)
对象的数组:模拟T次投掷骰子的Counter对象的用例: Rolls.java 如下:所用类列表:Counter, StdOut, StdRandom 见page42 public class Rol ...
- jQuery选择器之层次选择器Demo
测试代码: 02-层次选择器.html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &quo ...
- Intent的4种传值方法总结
xml 代码: <Button android:id="@+id/button1" android:layout_width="wrap_conte ...
- Mysql按时间段分组查询来统计会员的个数
1.使用case when方法(不建议使用)- 代码如下 复制代码 SELECT COUNT(DISTINCT user_id) user_count, CASE WHEN cre ...