메모리 매핑된 장치의 페이지 매핑이 작동하지 않습니다.

메모리 매핑된 장치의 페이지 매핑이 작동하지 않습니다.

파일에 자세히 설명된 단계를 사용하여 /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에 해당하는 물리적 주소를 찾으려고 하면 페이지 맵 파일에서 Page Not Found를 반환합니다. 검증 목적으로 이 작업을 수행하려고 합니다. 0x1b90000에서 mmap을 사용하여 0xb2efe000을 찾았기 때문에 물리적 주소가 존재한다는 것을 알고 있습니다. /proc/{pid}/pagemap 파일에 물리적 주소가 포함되지 않은 이유를 누군가 설명할 수 있습니까?

답변1

짧은 답변: 페이지 매핑 인터페이스는 주소와 관련된 구조 페이지에 저장된 정보를 노출합니다. I/O 주소는 연관된 구조 페이지가 없는 원시 pfn 맵이므로 노출은 0입니다.

더 긴 답변 물리적 주소(I/O 주소 포함)를 사용자 공간으로 다시 매핑하는 것은 호출을 통해 수행됩니다 remap_pfn_range. 이러한 다시 매핑된 주소는 아무 것도 struct page연결되지 않습니다(원래 pfn 매핑입니다). 이러한 주소는 특별하며 이 함수는 VM_PFNMAP이를 vma에 설정한다는 점을 기억하십시오.

페이지 매핑 인터페이스는 일련의 struct page주소 관련 필드를 노출합니다. 그러나 이 주소에는 그러한 구조가 없습니다. 따라서 페이지맵은 그냥 건너뜁니다.

페이지 매핑을 사용할 때 커널은 페이지 탐색을 수행하는 데 사용됩니다 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).
 */

페이지맵의 pte_hole은 단지 0개의 항목을 넣습니다(몇 가지 추가 플래그를 모듈로 VM_SOFTDIRTY). 그렇기 때문에 볼 수 없는 것입니다...

나는 매핑된 물리적 주소를 검색할 수 있는 커널 인터페이스를 알지 못합니다. 그러나 커널 모듈을 사용하거나 crash.

관련 정보