繁体   English   中英

Linux页面表的过程

[英]Linux page table of the process

Intel core i5, Ubunu 16.04

我在读有关内存分页这里现在试图用它来试验。 我写了一个简单的汇编程序来获取Segmentation Fault并在gdb中运行。 这里是:

 section .text
     global _start

 _start:
     mov rax, 0xFFFFFFFFFFFF0A31
     mov [val], eax
     mov eax, 4
     mov ebx, 1
     mov ecx, val
     mov edx, 2

     int 0x80

     mov eax, 1
     int 0x80

 segment .bss
     dummy resb 0xFFA
     val resb 1

我将它组装并链接到64位ELF静态可执行文件中。

据我所知,每个进程都有自己的页表, cr3注册指向该表。 现在我想自己查看页面表? 是否有可能在Linux中找到有关进程页表的信息?

您需要将编译为内核模块的程序读取页表。 我相信有些项目可以做到这一点。

看看这里: https//github.com/jethrogb/ptdump

似乎描述了你想要的东西

您可以在/proc/PID/smaps看到进程的所有映射。 这告诉您在不获取SIGSEGV的情况下可以访问的内容。

这是一样的东西作为你的CR3页表,因为内核并不总是“线”所有的映射。 即硬件页面错误并不总是SIGSEGV:内核页面错误处理程序检查您的进程是否逻辑上已映射该内存并更正该情况,或者您是否确实违反了内存保护。


mmap()系统调用之后,或者在进程启动以映射文本/数据/ BSS段时,您在逻辑上已经映射了内存,但Linux可能已经决定是懒惰的并且还没有提供任何物理页面。 (例如,页面可能尚未在页面缓存中,因此在您尝试实际触摸该内存并出现页面错误之前无需阻止)。

或者对于BSS内存,多个逻辑页面可能会开始写入映射到零的相同物理页面的写入时复制。 尽管根据Unix语义,您的内存是读写的,但页表实际上只具有只读映射。 编写页面会出现页面错误,内核会在新的零物理页面指向该条目,然后在出现故障的指令返回到您的进程(然后将重新运行并成功)。

无论如何,这并不直接回答你的问题,但可能是你真正想要的一部分。 如果你想深入了解,那么确实可以看到实际的页面表,但通常不需要这样做。 smaps可以告诉你有多少映射驻留在内存中。

另请参阅/ proc / pid / smaps中pss的含义,了解字段的含义。


顺便说一下为什么在64位虚拟地址与物理地址(52位长)相比,4位短(48位长)? 一个很好的4级页表格式图(以及2M / 1G大页面如何适应)。

我写了一个简单的汇编程序来获取Segmentation Fault并在gdb中运行....据我所知,每个进程都有自己的Page表,其中cr3注册指向。 现在我想自己查看页面表? 是否有可能在Linux中找到有关进程页表的信息?

操作系统维护页表。 它们受到保护,不受用户模式访问(正如您尝试的那样)。

要了解保护的工作原理,您需要了解处理器模式(例如,内核和用户)之间的差异以及处理器在这些模式之间切换的方式。

但是,简而言之,尝试编写代码来检查页面表是否是一个死胡同。 您最好从书本中学习页表结构,而不是尝试编写代码。 我建议查看英特尔手册。

https://software.intel.com/en-us/articles/intel-sdm

可悲的是,这是相当干燥的,英特尔编写了我见过的最糟糕的处理器手册。 我建议专门查看64位模式。 英特尔的32位过于复杂。 如果有关于段的讨论,那么您正在读取32位并且可以忽略它。 英特尔的文档从未指定地址是物理的还是逻辑的。 因此,您可能需要查看在线讲座以进行说明。

要补充此读数,您可以查看Linux源代码。 https://github.com/torvalds/linux

总而言之,您需要两个先决条件才能到达目的地:(1)处理器模式; (2)页表结构。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM