进程的 Linux 页 table
Linux page table of the process
Intel core i5, Ubunu 16.04
我正在阅读 gdb 中的内存分页 here and now trying to experiment with it. 和 运行。这是:
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
我assemble和link把这个变成64位ELF静态executable.
据我所知,每个进程都有自己的页面 Table,cr3
寄存器指向该页面。现在我想自己看看页面table?是否可以在 Linux 中找到有关进程页面 table 的信息?
您需要将程序编译为内核模块才能读取页表。我相信有一些项目可以做到这一点。
看这里:https://github.com/jethrogb/ptdump
似乎描述了你想要的
您可以在 /proc/PID/smaps
中看到您的进程的所有映射。这告诉您无需获得 SIGSEGV 即可访问的内容。
这 与您的 cr3 页面 table 不同,因为内核并不总是 "wire" 您的所有映射.即硬件页面错误并不总是 SIGSEGV:内核页面错误处理程序会检查您的进程是否在逻辑上映射了该内存并纠正了这种情况,或者您是否确实违反了内存保护。
在 mmap()
系统调用之后,或者在进程启动时映射文本/数据/BSS 段,逻辑上你已经映射了内存,但是 Linux 可能决定懒惰而不提供任何物理页面呢。 (例如,也许这些页面还不在页面缓存中,因此在您尝试实际访问该内存并出现页面错误之前无需阻塞)。
或者对于 BSS 内存,多个逻辑页面可能会开始写时复制映射到相同的零物理页面。即使根据 Unix 语义,您的内存是可读写的,页面 tables 实际上将具有只读映射。写一个页面会出现页面错误,内核会将该条目指向一个新的零物理页面,然后再返回到出错指令处的进程(然后重新 运行 并成功)。
无论如何,这并不能直接回答您的问题,但可能是您真正想要的内容的一部分。如果你想深入了解,那么一定要看看实际的页面 tables,但你通常不需要这样做。 smaps
可以告诉您有多少映射驻留在内存中。
另请参阅 what does pss mean in /proc/pid/smaps 以了解有关字段含义的详细信息。
顺便说一句,请参阅 4 级页面 table 格式的漂亮图表(以及 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. Now I would like to look at the page table myself? Is it possible to find info about process page table in Linux?
操作系统维护页面 tables。它们受到用户模式访问的保护(正如您尝试做的那样)。
要了解保护的工作原理,您需要了解处理器模式(例如,内核模式和用户模式)之间的区别以及处理器如何在这些模式之间切换。
但是,简而言之,尝试编写代码来检查页面 tables 就像您正在做的那样是一条死胡同。您最好从书本中学习页面 table 的结构,而不是尝试编写代码。我建议看看英特尔手册。
https://software.intel.com/en-us/articles/intel-sdm
可悲的是,这相当枯燥,英特尔编写了我见过的最糟糕的处理器手册。我建议专门查看 64 位模式。 Intel 的 32 位过于复杂。如果有谈论段,你正在阅读 32 位并且可以忽略它。 Intel 的文档从未指定地址是物理地址还是逻辑地址。因此,您可能需要查看在线讲座以进行说明。
为了补充阅读内容,您可以查看 Linux 源代码。 https://github.com/torvalds/linux
总而言之,您似乎需要两个先决条件才能到达目的地:(1) 处理器模式;和 (2) 页 table 结构。
Intel core i5, Ubunu 16.04
我正在阅读 gdb 中的内存分页 here and now trying to experiment with it.
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
我assemble和link把这个变成64位ELF静态executable.
据我所知,每个进程都有自己的页面 Table,cr3
寄存器指向该页面。现在我想自己看看页面table?是否可以在 Linux 中找到有关进程页面 table 的信息?
您需要将程序编译为内核模块才能读取页表。我相信有一些项目可以做到这一点。
看这里:https://github.com/jethrogb/ptdump
似乎描述了你想要的
您可以在 /proc/PID/smaps
中看到您的进程的所有映射。这告诉您无需获得 SIGSEGV 即可访问的内容。
这 与您的 cr3 页面 table 不同,因为内核并不总是 "wire" 您的所有映射.即硬件页面错误并不总是 SIGSEGV:内核页面错误处理程序会检查您的进程是否在逻辑上映射了该内存并纠正了这种情况,或者您是否确实违反了内存保护。
在 mmap()
系统调用之后,或者在进程启动时映射文本/数据/BSS 段,逻辑上你已经映射了内存,但是 Linux 可能决定懒惰而不提供任何物理页面呢。 (例如,也许这些页面还不在页面缓存中,因此在您尝试实际访问该内存并出现页面错误之前无需阻塞)。
或者对于 BSS 内存,多个逻辑页面可能会开始写时复制映射到相同的零物理页面。即使根据 Unix 语义,您的内存是可读写的,页面 tables 实际上将具有只读映射。写一个页面会出现页面错误,内核会将该条目指向一个新的零物理页面,然后再返回到出错指令处的进程(然后重新 运行 并成功)。
无论如何,这并不能直接回答您的问题,但可能是您真正想要的内容的一部分。如果你想深入了解,那么一定要看看实际的页面 tables,但你通常不需要这样做。 smaps
可以告诉您有多少映射驻留在内存中。
另请参阅 what does pss mean in /proc/pid/smaps 以了解有关字段含义的详细信息。
顺便说一句,请参阅
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. Now I would like to look at the page table myself? Is it possible to find info about process page table in Linux?
操作系统维护页面 tables。它们受到用户模式访问的保护(正如您尝试做的那样)。
要了解保护的工作原理,您需要了解处理器模式(例如,内核模式和用户模式)之间的区别以及处理器如何在这些模式之间切换。
但是,简而言之,尝试编写代码来检查页面 tables 就像您正在做的那样是一条死胡同。您最好从书本中学习页面 table 的结构,而不是尝试编写代码。我建议看看英特尔手册。
https://software.intel.com/en-us/articles/intel-sdm
可悲的是,这相当枯燥,英特尔编写了我见过的最糟糕的处理器手册。我建议专门查看 64 位模式。 Intel 的 32 位过于复杂。如果有谈论段,你正在阅读 32 位并且可以忽略它。 Intel 的文档从未指定地址是物理地址还是逻辑地址。因此,您可能需要查看在线讲座以进行说明。
为了补充阅读内容,您可以查看 Linux 源代码。 https://github.com/torvalds/linux
总而言之,您似乎需要两个先决条件才能到达目的地:(1) 处理器模式;和 (2) 页 table 结构。