输出虚拟地址对应物理地址的程序
这是一个可以在程序内输出本进程中虚拟地址实际对应的物理地址,可以用来探究linux内存管理系统。
注意:由于一些原因,此程序未能找到在lab machine上成功运行的方法,因此需要在虚拟机上运行。
文件结构
1 | vm.h vm.c - 实现了由虚拟地址计算物理地址的函数,请勿修改 |
其中,vm.h
与vm.c
核心代码来源于网络,为了方便调用,此处做了适当的微调与封装。
使用方法
函数接口
在vm.h
与vm.c
中,封装了一个函数,其可以根据传入的虚拟地址输出物理地址:
1 | void show_pa(void* va, const char* info); |
函数参数
va - 需要查看其物理地址的虚拟地址
info - 输出时首先输出的字符串,方便查看;如果为空字符串,则改为输出进程号
函数效果
会按如下格式输出一行:
1 | {info}: virtual addr = {va}, physical addr = {pa} |
如果info
为空串,则{info}
会替换为pid = {进程号}
;
如果物理地址转化成功,则{pa}
为16进制物理地址,否则为错误信息(包括缺页、权限不足失败等)。
调用方法
新建一个.c
文件,包含vm.h
头文件后即可直接调用:
1 |
可以在自己的代码中调用此函数观察某些变量的物理地址。
实例:cow.c
一个简单的例子,其fork
出一个子进程,最初两个进程同一变量的物理地址一致,而父进程写变量时发生写时复制,父进程该变量的物理地址变化。代码如下:
1 | /* copy on write */ |
编译
由于show_pa
函数的定义在vm.c
中,因此编译命令需要包含vm.c
,以编译上述cow.c
为例:
1 | $ gcc cow.c vm.c -g -Wall -o vm |
将得到名为vm
的可执行文件。
运行 (重要!)
如果直接运行出现了如下情况(以上述cow.c
编译出的可执行文件vm
为例):
1 | pid = 52128: virtual addr = 0x55d38e576010, physical addr = 10 |
物理地址最多只有3个16进制数,不足4KB,即只输出了页内偏移。这是权限原因导致的,在lab machine上未能找到解决方案,但在自己的虚拟机/双系统上可以解决。
如果编译出的可执行文件为vm
,则可以通过如下指令运行:
1 | $ sudo setcap cap_sys_admin=eip vm |
其中,第一条命令在每次编译后需要运行,若先前已运行过且没有重新编译则不需要。注意:两条命令sudo
都是必要的。以此法的运行结果如下(每次运行可能不同):
1 | pid = 52128: virtual addr = 0x55d38e576010, physical addr = 26541010 |
可以观察到:父进程52127
在修改了变量c
的值后发生了写时复制。
更多实例
global.c
1 | /* anonymous file and CoW */ |
首先定义了一个较大的全局变量int array[1024][1024]
,注意array[i][0]
与array[i+1][0]
正好相差4KB。
之后执行如下过程:
- 直接查看它们的物理地址(缺页)
- 经过一趟读操作后查看它们的物理地址
- 对部分进行写操作后查看它们的物理地址
详细细节请参阅源代码,其可能的输出如下:
1 | array[1][0]: virtual addr = 0x55d619f68040, physical addr = page present is 0 |
注意到,在经历读写操作前是缺页状态(前4行array[1][0]-array[4][0]
),但修改程序后发现array[0][0]
在读写前并未缺页,请思考可能的原因。
mmap.c
1 |
|
此程序mmap了两个私有页与一个共享页,并通过fork观察私有页与共享页在写时复制的区别,具体过程请见源代码。
值得注意的是,此程序fork后,子进程先写私有页触发写时复制,而后父进程写同一变量时并未发生复制,这表明内核维护了私有页面的引用数,若引用数为1则不会复制。
以下是一个可能的输出:
1 | private1: virtual addr = 0x7fb9ab92c000, physical addr = page present is 0 |
附录
vm.h
1 | /** |
vm.c
1 | /* Do not modify this file unless you know what you are doing */ |
输出虚拟地址对应物理地址的程序
http://spiritedawaycn.github.io/2020/12/14/physical-address/