Comment décoder les entrées/proc/pid / pagemap sous Linux?

j'essaie de déchiffrer comment utiliser /proc/pid/pagemap pour obtenir l'adresse physique d'un ensemble donné de pages. Supposons que dans le fichier / proc/pid / maps, j'obtienne l'adresse virtuelle afa2d000-afa42000 qui correspond au tas. Ma question Est Comment puis-je utiliser cette information pour parcourir le fichier pagemap et trouver les cadres de page physiques correspondent à l'adresse afa2d000-afa42000.

l'entrée/proc/pid / pagemap est en format binaire. Est-il des outils pour aider à l'analyse de cette fichier?

8

4 réponses

essayez ceci http://www.eqware.net/Articles/CapturingProcessMemoryUsageUnderLinux / Il peut analyser les pagemap pour vous, par exemple, si l'adresse virtuelle vous êtes intéressé est dans le tas qui est 0x055468 : = 0004c000-0005a000 rw-p 00000000 00: 00 0 [tas] : 86000000000FD6D6 : 0600000000000000

: 0600000000000000

: 86000000000FE921

: 86000000000FE922

: 0600000000000000

: 86000000000FD5AD

: 86000000000FD6D4

: 86000000000FD5F8

: 86000000000FD5FA = > 9th

supposons que la taille de la page soit de 4KB, et (0x055468 - 0x4c000) mod 4K = 9, Afin que le numéro de châssis de votre page est le 9ème cadres de page = = > : 86000000000FD5FA Donc le pfn physique est 0xFD5FA000 (prendre les 55 derniers bits et fois la taille de la page) plus l'écart: ( 0x055468 - 0x4c000-9*4K) = 0x468 = = > l'adresse physique est 0xFD5FA000 + 0x468 = 0xfd5fa468

2
répondu I Chun Lin 2013-07-02 06:45:12

j'espère que ce lien vous aidera. C'est un outil très simple, et déterminer l'adresse à laquelle vous devez accéder est très simple.: http://fivelinesofcode.blogspot.com/2014/03/how-to-translate-virtual-to-physical.html

3
répondu Dmitry 2014-03-01 08:48:30

documentation du noyau Linux

Linux kernel doc décrivant le format: 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

C analyseur de fonction

GitHub en amont .

#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, &data, sizeof(data),
                (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;
}

exemple de programmes exécutables qui l'utilisent:

1

dans le cas où les gens veulent faire cela à partir de la rouille, j'ai ajouté une implémentation Rust afin que vous puissiez naviguer facilement /proc/$pid/maps et /proc/$pid/pagemap : https://crates.io/crates/vm-info

0
répondu mpierce 2018-02-04 23:01:22