簡體   English   中英

如何從Linux中的用戶空間找到變量的物理地址?

[英]How to find the physical address of a variable from user-space in Linux?

我想找到在用戶空間進程中定義的變量的物理地址? 有沒有辦法使用root權限來做到這一點?

正如之前部分回答的那樣,普通程序不需要擔心物理地址,因為它們在虛擬地址空間中運行並具有所有便利性。 此外,並非每個虛擬地址都有物理地址,它們可能屬於映射文件或交換頁面。 然而,有時看到這個映射可能會很有趣,即使是在用戶空間。

為此,Linux 內核通過/proc中的一組文件將其映射公開給用戶空間。 文檔可以在這里找到。 簡短的摘要:

  1. /proc/$pid/maps提供了虛擬地址的映射列表以及附加信息,例如映射文件的相應文件。
  2. /proc/$pid/pagemap提供有關每個映射頁面的更多信息,包括物理地址(如果存在)。

這個網站提供了一個 C 程序,它使用這個接口轉儲所有正在運行的進程的映射,並解釋它的作用。

#include "stdio.h"
#include "unistd.h"
#include "inttypes.h"

uintptr_t vtop(uintptr_t vaddr) {
    FILE *pagemap;
    intptr_t paddr = 0;
    int offset = (vaddr / sysconf(_SC_PAGESIZE)) * sizeof(uint64_t);
    uint64_t e;

    // https://www.kernel.org/doc/Documentation/vm/pagemap.txt
    if ((pagemap = fopen("/proc/self/pagemap", "r"))) {
        if (lseek(fileno(pagemap), offset, SEEK_SET) == offset) {
            if (fread(&e, sizeof(uint64_t), 1, pagemap)) {
                if (e & (1ULL << 63)) { // page present ?
                    paddr = e & ((1ULL << 54) - 1); // pfn mask
                    paddr = paddr * sysconf(_SC_PAGESIZE);
                    // add offset within page
                    paddr = paddr | (vaddr & (sysconf(_SC_PAGESIZE) - 1));
                }   
            }   
        }   
        fclose(pagemap);
    }   

    return paddr;
}   

首先,你為什么要這樣做? 現代 VM 系統的目的是將應用程序程序員從物理內存布局的復雜性中移除。 給他們每個人自己統一的地址空間,讓他們的生活更輕松。

如果您確實想這樣做,您幾乎肯定需要使用內核模塊。 以正常方式獲取變量的虛擬地址,使用它來索引進程頁表並讀取您找到的值(幀的物理地址)。 然后加上頁偏移量,得到完整的物理地址。 請注意,啟用分頁時您將無法使用此地址。

(如果幸運的話,您可以從 /proc 文件系統中獲取 VM 區域的幀地址,因此不需要編寫內核模塊。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM