简体   繁体   English

Linux页面表的过程

[英]Linux page table of the process

Intel core i5, Ubunu 16.04

I'm reading about the memory paging here and now trying to experiment with it. 我在读有关内存分页这里现在试图用它来试验。 I wrote a simple assembly program for getting Segmentation Fault and ran in gdb. 我写了一个简单的汇编程序来获取Segmentation Fault并在gdb中运行。 Here it is: 这里是:

 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

I assemble and link this into a 64-bit ELF static executable. 我将它组装并链接到64位ELF静态可执行文件中。

As far as I read each process has its own Page Table which cr3 register points to. 据我所知,每个进程都有自己的页表, cr3注册指向该表。 Now I would like to look at the page table myself? 现在我想自己查看页面表? Is it possible to find info about process page table in Linux? 是否有可能在Linux中找到有关进程页表的信息?

You would need to have a program compiled as a kernel module to read the page tables. 您需要将编译为内核模块的程序读取页表。 I am sure there are projects out there to do that. 我相信有些项目可以做到这一点。

Take a look here: https://github.com/jethrogb/ptdump 看看这里: https//github.com/jethrogb/ptdump

Seems to describe what you want 似乎描述了你想要的东西

You can see all the mappings your process has in /proc/PID/smaps . 您可以在/proc/PID/smaps看到进程的所有映射。 This tells you what you can access without getting a SIGSEGV. 这告诉您在不获取SIGSEGV的情况下可以访问的内容。

This is not the same thing as your cr3 page table, because the kernel doesn't always "wire" all your mappings. 这是一样的东西作为你的CR3页表,因为内核并不总是“线”所有的映射。 ie a hardware page fault isn't always a SIGSEGV: the kernel page-fault handler checks whether your process logically has that memory mapped and corrects the situation, or whether you really did violate the memory protections. 即硬件页面错误并不总是SIGSEGV:内核页面错误处理程序检查您的进程是否逻辑上已映射该内存并更正该情况,或者您是否确实违反了内存保护。


After an mmap() system call, or on process startup to map the text / data / BSS segments, you logically have memory mapped, but Linux might have decided to be lazy and not provide any physical pages yet. mmap()系统调用之后,或者在进程启动以映射文本/数据/ BSS段时,您在逻辑上已经映射了内存,但Linux可能已经决定是懒惰的并且还没有提供任何物理页面。 (eg maybe the pages aren't in the pagecache yet, so there's no need to block until you try to actually touch that memory and get a page fault). (例如,页面可能尚未在页面缓存中,因此在您尝试实际触摸该内存并出现页面错误之前无需阻止)。

Or for BSS memory, multiple logical pages might start out copy-on-write mapped to the same physical page of zeros. 或者对于BSS内存,多个逻辑页面可能会开始写入映射到零的相同物理页面的写入时复制。 Even though according to Unix semantics your memory is read-write, the page tables would actually have read-only mappings. 尽管根据Unix语义,您的内存是读写的,但页表实际上只具有只读映射。 Writing a page will page-fault, and the kernel will point that entry at a new physical page of zeros before returning to your process at the instruction which faulted (which will then be re-run and succeed). 编写页面会出现页面错误,内核会在新的零物理页面指向该条目,然后在出现故障的指令返回到您的进程(然后将重新运行并成功)。

Anyway, this doesn't directly answer your question, but might be part of what you actually want. 无论如何,这并不直接回答你的问题,但可能是你真正想要的一部分。 If you want to look under the hood, then sure have fun looking at the actual page tables, but you generally don't need to do that. 如果你想深入了解,那么确实可以看到实际的页面表,但通常不需要这样做。 smaps can tell you how much of a mapping is resident in memory. smaps可以告诉你有多少映射驻留在内存中。

See also what does pss mean in /proc/pid/smaps for details on what the fields mean. 另请参阅/ proc / pid / smaps中pss的含义,了解字段的含义。


BTW, see Why in 64bit the virtual address are 4 bits short (48bit long) compared with the physical address (52 bit long)? 顺便说一下为什么在64位虚拟地址与物理地址(52位长)相比,4位短(48位长)? for a nice diagram of the 4-level page table format (and how 2M / 1G hugepages fit in). 一个很好的4级页表格式图(以及2M / 1G大页面如何适应)。

I wrote a simple assembly program for getting Segmentation Fault and ran in gdb.... As far as I read each process has its own Page Table which cr3 register points to. 我写了一个简单的汇编程序来获取Segmentation Fault并在gdb中运行....据我所知,每个进程都有自己的Page表,其中cr3注册指向。 Now I would like to look at the page table myself? 现在我想自己查看页面表? Is it possible to find info about process page table in Linux? 是否有可能在Linux中找到有关进程页表的信息?

The operating system maintains the page tables. 操作系统维护页表。 They are protected from user-mode access (as you are trying to do). 它们受到保护,不受用户模式访问(正如您尝试的那样)。

To understand how protection works you are going to need to understand the difference between processor modes (eg, Kernel and User) and how the processor shifts between these modes. 要了解保护的工作原理,您需要了解处理器模式(例如,内核和用户)之间的差异以及处理器在这些模式之间切换的方式。

In short, however, trying to write code to examine page tables as you are doing is a dead end. 但是,简而言之,尝试编写代码来检查页面表是否是一个死胡同。 You are better off learning about page table structure from books rather than trying to write code. 您最好从书本中学习页表结构,而不是尝试编写代码。 I suggest looking at the Intel manuals. 我建议查看英特尔手册。

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

Sadly, this is rather dry and Intel writes the worst processor manuals I have seen. 可悲的是,这是相当干燥的,英特尔编写了我见过的最糟糕的处理器手册。 I recommend looking exclusively at 64-bit mode. 我建议专门查看64位模式。 Intel's 32-bit is overly complicated. 英特尔的32位过于复杂。 If there is talk about segments, you are reading 32-bit and can ignore it. 如果有关于段的讨论,那么您正在读取32位并且可以忽略它。 Intel's documentation never specifies whether addresses are physical or logical. 英特尔的文档从未指定地址是物理的还是逻辑的。 So you may need to look at on-line lectures for clarification. 因此,您可能需要查看在线讲座以进行说明。

To supplement this reading, you can look at the Linux Source code. 要补充此读数,您可以查看Linux源代码。 https://github.com/torvalds/linux https://github.com/torvalds/linux

To conclude, it appears you need two prerequisites to get where you want to go: (1) processor modes; 总而言之,您需要两个先决条件才能到达目的地:(1)处理器模式; and (2) page table structure. (2)页表结构。

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

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