我试图理解标题中提到的两个文件。我已经查阅了位数的含义;然而,我无法理解如何从中提取有用的信息(或者我只是以错误的方式进行了尝试)。
让我来解释一下:pagemaps是一个相当新的“特性”伪文件,其中包含分配给当前[pid]的虚拟页面的物理帧信息。也就是说,给定一个从地址x开始的虚拟页面,比如‘vas’表示虚拟地址开始,我可以使用vas对pagemap文件进行索引,以获取映射的物理页面帧的64位。这些位包含有关该虚拟页面的信息。但是,当我提取这些位并进行位移时,我会迷失在我所看到的内容中。
这些位的表示如下:0-54是页面帧号,55-60是页面位移,第63位是存在位,还有其他我不太感兴趣的位。在使用/proc/[pid]/maps中的vas地址进行一些映射后,似乎每个进程的页面都被交换了,即第63位始终为零。 :(
我想问题应该是,我应该如何有效地使用pagemaps来获得由/proc/[pid]/maps给出的地址的等效物理地址?
公平地说,我几天前发布了类似的问题,但方法有点不同。
如果有人能在这个问题上提供一些帮助,我将非常感激。
===编辑===
回应下面的评论:
我正在读取/proc/[pid]/maps中的一行,这些行看起来像:
00400000-00401000 r-xp 00000000 08:01 8915461 /home/janjust/my_programs/shared_mem 7ffffef1b000-7ffffef3c000 rw-p 00000000 00:00 0 [stack]
然后我提取它所涉及的虚拟页数,并索引一个二进制文件/proc/[pid]/pagemaps,对于每个虚拟页面,我都可以提取它分配给的物理页面。
输出看起来像:
00400000-00401000 r-xp 00000000 08:01 8915461 /home/janjust/my_programs/shared_mem num_pages: 1 : 86000000001464C6
虚拟范围内每个虚拟页的一个物理地址。
读取该行并提取物理地址的代码如下:
然而,尽管我认为我得到了正确的输出,但索引似乎要么类型不匹配,要么发生了其他问题: 例如,maps中的[shared mem]行给出了错误的索引; 然而,我仍然能够扫描二进制文件并获取物理页面地址。
以下是该输出的示例:
让我来解释一下:pagemaps是一个相当新的“特性”伪文件,其中包含分配给当前[pid]的虚拟页面的物理帧信息。也就是说,给定一个从地址x开始的虚拟页面,比如‘vas’表示虚拟地址开始,我可以使用vas对pagemap文件进行索引,以获取映射的物理页面帧的64位。这些位包含有关该虚拟页面的信息。但是,当我提取这些位并进行位移时,我会迷失在我所看到的内容中。
这些位的表示如下:0-54是页面帧号,55-60是页面位移,第63位是存在位,还有其他我不太感兴趣的位。在使用/proc/[pid]/maps中的vas地址进行一些映射后,似乎每个进程的页面都被交换了,即第63位始终为零。 :(
我想问题应该是,我应该如何有效地使用pagemaps来获得由/proc/[pid]/maps给出的地址的等效物理地址?
公平地说,我几天前发布了类似的问题,但方法有点不同。
如果有人能在这个问题上提供一些帮助,我将非常感激。
===编辑===
回应下面的评论:
我正在读取/proc/[pid]/maps中的一行,这些行看起来像:
00400000-00401000 r-xp 00000000 08:01 8915461 /home/janjust/my_programs/shared_mem 7ffffef1b000-7ffffef3c000 rw-p 00000000 00:00 0 [stack]
然后我提取它所涉及的虚拟页数,并索引一个二进制文件/proc/[pid]/pagemaps,对于每个虚拟页面,我都可以提取它分配给的物理页面。
输出看起来像:
00400000-00401000 r-xp 00000000 08:01 8915461 /home/janjust/my_programs/shared_mem num_pages: 1 : 86000000001464C6
虚拟范围内每个虚拟页的一个物理地址。
读取该行并提取物理地址的代码如下:
74 /* process /proc/pid/maps, by line*/
75 while(fgets(line, 256, in_map) != NULL){
76 unsigned long vas;
77 unsigned long vae;
78 int num_pages;
79
80 //print line
81 printf("%s", line);
82
83 /*scan for the virtual addresses*/
84 n = sscanf(line, "%lX-%lX", &vas, &vae);
85 if(n != 2){
86 printf("Involid line read from %s\n",maps);
87 continue;
88 }
89
90 num_pages = (vae - vas) / PAGE_SIZE;
91 printf("num_pages: %d\n", num_pages);
92
93 if(num_pages > 0){
94 long index = (vas / PAGE_SIZE) * sizeof(unsigned long long);
95 off64_t o;
96 ssize_t t;
97
98 /* seek to index in pagemaps */
99 o = lseek64(pm, index, SEEK_SET);
100 if (o != index){
101 printf("Error seeking to o:%ld, index:%ld.\n", o, index);
102 }
103
104 /* map the virtual to physical page */
105 while(num_pages > 0){
106 unsigned long long pa;
107
108 /* Read a 64-bit word from each pagemap file... */
109 t = read(pm, &pa, sizeof(unsigned long long));
110 if(t < 0){
111 printf("Error reading file \"%s\" \n", page_map);
112 goto next_line;
113 }
114 printf(": %016llX\n", pa);
然而,尽管我认为我得到了正确的输出,但索引似乎要么类型不匹配,要么发生了其他问题: 例如,maps中的[shared mem]行给出了错误的索引; 然而,我仍然能够扫描二进制文件并获取物理页面地址。
以下是该输出的示例:
969 7f7f08d58000-7f7f08d59000 rw-s 00000000 00:04 0 /SYSV00003039 (deleted)
970 num_pages: 1
971 Error seeking to o:-1081840960, index:273796065984.
972 : 8600000000148267
好的,最后我应该说一下,这是在64位操作系统下出现的问题,在32位操作系统下不会出现。
/proc/[pid]/pagemap
中的索引。在你的代码(以及我的代码)中,你有这个:`long index = (vas / PAGE_SIZE) * sizeof(unsigned long long);`
我想知道的是PAGE_SIZE
。大多数架构都允许使用大页 - 例如,在x86上,页面可以是4kB或4MB。这不会使使用统一的PAGE_SIZE
索引/proc/[pid]/pagemap
变得不可行吗? - Ted Middleton