記憶體映射裝置上的頁面映射不起作用

記憶體映射裝置上的頁面映射不起作用

我試圖使用 /proc/{pid}/pagemap 檔案使用檔案中詳細的步驟來尋找堆疊變數、堆疊變數和記憶體映射外設位址的物理位址:http://lxr.free-electrons.com/source/Documentation/vm/pagemap.txt。詳細的過程適用於堆疊和堆疊變數。但是,對於記憶體映射外設,在 /proc/{pid}/pagemap 檔案中找不到頁面。 'cat /proc/{pid}/maps' 的輸出是:

00008000-0000a000 r-xp 00000000 b3:02 289852     /home/linaro/ocm_test/write-memory
00011000-00012000 r--p 00001000 b3:02 289852     /home/linaro/ocm_test/write-memory
00012000-00013000 rw-p 00002000 b3:02 289852     /home/linaro/ocm_test/write-memory
00013000-00034000 rw-p 00000000 00:00 0          [heap]
b2efe000-b6dfe000 rw-s 00001000 b3:02 284849     /dev/uio0
b6dfe000-b6ed2000 r-xp 00000000 b3:02 282416     /lib/arm-linux-gnueabihf/libc-2.15.so
b6ed2000-b6eda000 ---p 000d4000 b3:02 282416     /lib/arm-linux-gnueabihf/libc-2.15.so
b6eda000-b6edc000 r--p 000d4000 b3:02 282416     /lib/arm-linux-gnueabihf/libc-2.15.so
b6edc000-b6edd000 rw-p 000d6000 b3:02 282416     /lib/arm-linux-gnueabihf/libc-2.15.so
b6edd000-b6ee0000 rw-p 00000000 00:00 0 
b6ee0000-b6ee2000 r-xp 00000000 b3:02 27519      /usr/lib/libinterface.so
b6ee2000-b6ee9000 ---p 00002000 b3:02 27519      /usr/lib/libinterface.so
b6ee9000-b6eea000 r--p 00001000 b3:02 27519      /usr/lib/libinterface.so
b6eea000-b6eeb000 rw-p 00002000 b3:02 27519      /usr/lib/libinterface.so
b6efb000-b6f12000 r-xp 00000000 b3:02 282407     /lib/arm-linux-gnueabihf/ld-2.15.so
b6f13000-b6f14000 rw-p 00000000 00:00 0 
b6f14000-b6f15000 rw-s 00000000 b3:02 284849     /dev/uio0
b6f15000-b6f19000 rw-p 00000000 00:00 0 
b6f19000-b6f1a000 r--p 00016000 b3:02 282407     /lib/arm-linux-gnueabihf/ld-2.15.so
b6f1a000-b6f1b000 rw-p 00017000 b3:02 282407     /lib/arm-linux-gnueabihf/ld-2.15.so
bee36000-bee57000 rw-p 00000000 00:00 0          [stack]
bef1f000-bef20000 r-xp 00000000 00:00 0          [sigpage]
ffff0000-ffff1000 r-xp 00000000 00:00 0          [vectors]

當我嘗試尋找 0x00013000 或 0xbee36000 的實體位址時,它會正常運作。但是,當我嘗試尋找屬於 /dev/uio0 的 0xb2efe000 對應的實體位址時,頁面對應檔案會傳回未找到頁面。我試著這樣做是為了驗證目的。我知道物理位址存在,因為我在忽略 0x1b90000 上使用 mmap 來查找 0xb2efe000。有人可以解釋為什麼 /proc/{pid}/pagemap 檔案不包含物理位址嗎?

答案1

簡短回答:頁面映射介面公開儲存在與位址關聯的結構體頁面中的資訊。 I/O 位址是原始 pfn 映射,沒有關聯的結構頁,因此暴露為零。

更長的答案 將實體位址(包括 I/O 位址)重新對應到用戶空間是透過呼叫remap_pfn_range.這些重新映射的位址沒有struct page與之關聯(它們是原始 pfn 映射)。要記住這些位址是特殊的,這個函數VM_PFNMAP在 vma 上設定。

頁面映射介面公開了一系列struct page與位址相關的欄位。但這些地址沒有這樣的結構。所以 pagemap 只是跳過它們:

當使用頁面對應時,核心使用 進行頁面遍歷walk_page_range。標記為 vmas 的VM_PFNMAP處理方式有所不同:

/*
 * vma(VM_PFNMAP) doesn't have any valid struct pages behind VM_PFNMAP
 * range, so we don't walk over it as we do for normal vmas. However,
 * Some callers are interested in handling hole range and they don't
 * want to just ignore any single address range. Such users certainly
 * define their ->pte_hole() callbacks, so let's delegate them to handle
 * vma(VM_PFNMAP).
 */

pagemap 的 pte_hole 只是放置一堆零條目(對 的一些附加標誌取模VM_SOFTDIRTY)。這就是為什麼你看不到它...

我不知道有任何核心介面允許您檢索此類映射的物理位址。但使用內核模組或使用crash.

相關內容