* 아직은 많이 부족하기 때문에 제가 자신이 생길 때 까지 본 글은 제 블로그에 대한 링크만 허용합니다.
가상메모리 주소를 실제메모리 주소로 변환해 보겠습니다.
실제로는 VAD 값을 뒤져 데이터를 확인 할 수도 있습니다. 하지만 본 예에서는 간단하게 !pte 를 통해 페이지 테이블 엔트리에서 저장하고 있는 값을 확인 하고 이를 통해 실제 주소를 확인 하도록 하겠습니다.
(출처 : http://blogs.technet.com/marcelofartura/archive/2008/11/20/how-to-manually-translate-virtual-addresses-into-physical-ones.aspx)
이제 부터 가상 메모리를 들여다 보도록 하겠습니다.
편의상 특정 가상 메모리 주소 b03b5000를 통해 확인 하겠습니다.
lkd> !pte b03b5000
VA b03b5000
PDE at 00000000C0602C08 PTE at 00000000C0581DA8
contains 000000000A6FD963 contains 00000000164B2963
pfn a6fd -G-DA--KWEV pfn 164b2 -G-DA—KWEV
페이지 테이블과 관련된 녀석들은 0xC0000000 정도에 몰려 있는 것을 볼 수 있습니다.
PDE at 00000000C0602C08 PTE at 00000000C0581DA8
여기서 잠깐 PDE는 C0602C08 에 위치하고 PTE C0581DA8 에 위치하는 것을 알 수 있습니다
내 실제로 커널에 페이지 테이블을 저장하는 공간은 가상 주소0xC0000000 정도에 위치하고 있습니다.
그림 윈도우즈 x86 시스템의 커널 메모리 공간 레이아웃
더불어 아래의 내용과 같이 실제 인덱스 위치 및 위에서 설명한 권한에 대한 부분이나 페이징 여부 외에 페이지에 대한 접속 여부 등등 많은 내용을 알 수 있습니다.
pfn a6fd -G-DA--KWEV pfn 164b2 -G-DA—KWEV
(참고 x86, x64 에 대한 페이지 디렉토리 엔트리와 페이지 테이블 엔트리에 대한 설정)
Bit | Display when set | Display when clear | Meaning |
0x200 | C | - | Copy on write. |
0x100 | G | - | Global. |
0x80 | L | - | Large page. This only occurs in PDEs, never in PTEs. |
0x40 | D | - | Dirty. |
0x20 | A | - | Accessed. |
0x10 | N | - | Cache disabled. |
0x8 | T | - | Write-through. |
0x4 | U | K | Owner (user mode or kernel mode). |
0x2 | W | R | Writeable or read-only. Only on multiprocessor computers and any computer running Windows Vista or later. |
0x1 | V | | Valid. |
| E | - | Executable page. For platforms that do not support a hardware execute/noexecute bit, including many x86 systems, the E is always displayed. |
(참고 IA64 에 대한 페이지 디렉토리 엔트리와 페이지 테이블 엔트리에 대한 설정)
Display when set | Display when clear | Meaning |
V | | Valid. |
U | K | Owner (user mode or kernel mode). |
D | - | Dirty. |
A | - | Accessed. |
W | R | Writeable or read-only. Only on multiprocessor computers and any computer running Windows Vista or later. |
E | - | Execute. |
C | - | Copy on write. |
그렇다면 실제 가상 주소 b03b5000 의 내용과 이 가상 주소를 조회하여 얻은 실제 물리 주소를 직접 찾아가 데이터를 비교해 보겠습니다.
먼저 가상 주소 b03b5000 의 데이터를 확인해 봤습니다.
lkd> dc b03b5000
b03b5000 00905a4d 00000003 00000004 0000ffff MZ..............
b03b5010 000000b8 00000000 00000040 00000000 ........@.......
b03b5020 00000000 00000000 00000000 00000000 ................
b03b5030 00000000 00000000 00000000 000000d8 ................
b03b5040 0eba1f0e cd09b400 4c01b821 685421cd ........!..L.!Th
b03b5050 70207369 72676f72 63206d61 6f6e6e61 is program canno
b03b5060 65622074 6e757220 206e6920 20534f44 t be run in DOS
b03b5070 65646f6d 0a0d0d2e 00000024 00000000 mode....$.......
자 그러면 우리가 방금 확인 했던 PTE에 들어있는 실제 물리 주소의 내용을 확인해 보겠습니다.
lkd> !pte b03b5000
VA b03b5000
PDE at 00000000C0602C08 PTE at 00000000C0581DA8
contains 000000000A6FD963 contains 00000000164B2963
이전에 설명했던 것과 같이 PFN 00000000164B2963 의 첫 20 비트 값이 실제 물리 페이지의 위치 입니다.
한번 보겠습니다.
실제 물리주소는 PTE에 있다고 말씀 드렸습니다. 그리고 이 PTE의 내용 중 첫 20비트를 확인 해 보니 164B2000 임을 확인 했습니다.
그리고 이 164B2000 주소에 b03b5000 의 뒷 12 비트를 더해 주면 실제 물리 주소가 됩니다.
이 경우에는 000 이니깐 더해 줘도 동일하게 164B2000가 됩니다.
실제 물리 주소인 164B2000의 값을 확인 해 보니 가상 메모리 주소와 일치함을 확인 할 수 있습니다.
lkd> dc /p 164B2000
b03b5000 00905a4d 00000003 00000004 0000ffff MZ..............
b03b5010 000000b8 00000000 00000040 00000000 ........@.......
b03b5020 00000000 00000000 00000000 00000000 ................
b03b5030 00000000 00000000 00000000 000000d8 ................
b03b5040 0eba1f0e cd09b400 4c01b821 685421cd ........!..L.!Th
b03b5050 70207369 72676f72 63206d61 6f6e6e61 is program canno
b03b5060 65622074 6e757220 206e6920 20534f44 t be run in DOS
b03b5070 65646f6d 0a0d0d2e 00000024 00000000 mode....$....…