Nar*_*uto 12 linux linux-kernel memory-address
我试图破译如何使用/ proc/pid/pagemap来获取给定页面集的物理地址.假设从/ proc/pid/maps,我得到对应堆的虚拟地址afa2d000-afa42000.我的问题是如何使用此信息遍历页面映射文件,并找到对应于地址afa2d000-afa42000的物理页面框架.
/ proc/pid/pagemap条目采用二进制格式.有没有工具可以帮助解析这个文件?
Linux内核文档
描述格式的 Linux 内核文档:https : //github.com/torvalds/linux/blob/v4.9/Documentation/vm/pagemap.txt
* Bits 0-54 page frame number (PFN) if present
* Bits 0-4 swap type if swapped
* Bits 5-54 swap offset if swapped
* Bit 55 pte is soft-dirty (see Documentation/vm/soft-dirty.txt)
* Bit 56 page exclusively mapped (since 4.2)
* Bits 57-60 zero
* Bit 61 page is file-page or shared-anon (since 3.5)
* Bit 62 page swapped
* Bit 63 page present
Run Code Online (Sandbox Code Playgroud)
C 解析器函数
#define _XOPEN_SOURCE 700
#include <fcntl.h> /* open */
#include <stdint.h> /* uint64_t */
#include <stdlib.h> /* size_t */
#include <unistd.h> /* pread, sysconf */
typedef struct {
uint64_t pfn : 54;
unsigned int soft_dirty : 1;
unsigned int file_page : 1;
unsigned int swapped : 1;
unsigned int present : 1;
} PagemapEntry;
/* Parse the pagemap entry for the given virtual address.
*
* @param[out] entry the parsed entry
* @param[in] pagemap_fd file descriptor to an open /proc/pid/pagemap file
* @param[in] vaddr virtual address to get entry for
* @return 0 for success, 1 for failure
*/
int pagemap_get_entry(PagemapEntry *entry, int pagemap_fd, uintptr_t vaddr)
{
size_t nread;
ssize_t ret;
uint64_t data;
nread = 0;
while (nread < sizeof(data)) {
ret = pread(pagemap_fd, ((uint8_t*)&data) + nread, sizeof(data) - nread,
(vaddr / sysconf(_SC_PAGE_SIZE)) * sizeof(data) + nread);
nread += ret;
if (ret <= 0) {
return 1;
}
}
entry->pfn = data & (((uint64_t)1 << 54) - 1);
entry->soft_dirty = (data >> 54) & 1;
entry->file_page = (data >> 61) & 1;
entry->swapped = (data >> 62) & 1;
entry->present = (data >> 63) & 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用它的可运行程序示例:
我希望这个链接会有所帮助。这是一个非常简单的工具,确定您需要访问的地址也非常简单: http:// Fivelinesofcode.blogspot.com/2014/03/how-to-translate-virtual-to-physical.html
小智 2
试试这个
http://www.eqware.net/Articles/CapturingProcessMemoryUsageUnderLinux/
它可以为您解析页面映射,例如,如果您感兴趣的虚拟地址位于堆中,即 0x055468 := 0004c000-0005a000 rw-p 00000000 00:00 0 [堆] : 86000000000FD6D6 : 0600000000000000
: 0600000000000000 :
86000000000FE921 : 86000000000FE922
:
0600000000000000 :
86000000000FD5AD :
86000000000FD6D4
: 86000000000FD5F8
: 86000000000FD5FA =>第9
假设页面大小为4KB,并且(0x055468 - 0x4c000) mod 4K = 9,那么你的页面的页框号就是第9个页框==>:86000000000FD5FA所以物理pfn是0xFD5FA000(取最后55位和时间)页大小)加上偏移量:( 0x055468 - 0x4c000 - 9*4K) = 0x468 ==> 物理地址为 0xFD5FA000 + 0x468 = 0xFD5FA468
归档时间: |
|
查看次数: |
8243 次 |
最近记录: |