手動玩轉虛擬地址到物理地址轉化

我們這次來根據dump動手來實際轉化一個虛擬地址到物理地址,此次的地址不是線性地址映射。

Target_Address_|________________logical|_physical______________|
               |     C:FFFFFF8008015000|             A:C549F000
 

上面0xFFFFFF8008015000就是虛擬地址,而我們努力的方向就是物理地址:0xC549F000。 讓我們朝這個方向一路高歌吧。

 

轉化的原理:

  • 根據TTBR(0/1)寄存器獲取到頁表的基地址
  • 頁表基地址+PGD_Index獲取PGD表中的一項,此項就是PMD表的基地址
  • 根據PDM基地址+PMD_Index獲取PMD中的一項,此項就是PTE表的基地址
  • 根據PTE基地址+PTE_Index獲取直接頁表的基地址
  • 根據直接頁表的地址+offset就可以獲取真正的物理地址

 

轉化之前先確認的是此地址是屬於用戶空間還是內核空間。

  • 用戶地址:頁表的基地址是mm_struct→pgd
  • 內核空間:  頁表的基地址是init_mm→pgd

 

很明顯我們需要轉化的地址是屬於內核空間的,則首先需要確認init_mm→pgd的值,它來了

init_mm = (
    mmap = 0x0,
    mm_rb = (rb_node = 0x0),
    vmacache_seqnum = 0x0,
    mm_rb_lock = (raw_lock = (cnts = (counter = 0x0), wlocked = 0x0, __lstate = (0x0, 0x0, 0x0), wai
    get_unmapped_area = 0x0,
    mmap_base = 0x0,
    mmap_legacy_base = 0x0,
    task_size = 0x0,
    highest_vm_end = 0x0,
    pgd_=_0xFFFFFF9B4FCA7000 -> (  //虛擬地址
      pgd = 0x000000017AC05003),   //虛擬地址裏面的值
    mm_users = (counter = 0x2),
    mm_count = (counter = 0x1),

前期條件: 

  • 虛擬地址:0xFFFFFF8008015000
  • init_mm→pgd的值:0xFFFFFF9B4FCA7000

 

PGD_Index = 虛擬地址>>30位 = (0xFFFFFF8008015000 >>30)&(0x200-1) = 0

PGD_entry_virt = 0xFFFFFF9B4FCA7000 + 0*8 = 0xFFFFFF9B4FCA7000

PGD_entry_phy = rd(0xFFFFFF9B4FCA7000) = 0x000000017AC05003

 

PMD_Index = 虛擬地址  >> 21位 = (0xFFFFFF8008015000 >>21)&(0x1ff) = 0x40

PMD_entry_virt = 0x000000017AC05003 + 0x40 * 8 = 0x000000017AC05000 + 0x40 *8 = 0x17AC05200

PMD_entry_phy = rd(0x17AC05200) = 0x17AC06003

 

PTE_Index = 虛擬地址 >> 12位 = (0xFFFFFF8008015000>>12)&(0x200-1)=0x15

PTE_entry_virt =  0x17AC06003 + 0x15 * 8 = 0x17AC06000 + 0x15*8= 0x17AC060A8

PTE_entry_phy = rd(0x17AC060A8) = 0xE00000C549F793

 

pfn = 0xE00000C549F793 >> 12 = 0xC549F

 

物理地址 = 0xC549F000 + 0x000 = 0xC549F000

上面之所以需要清空低12位,還有index*8都是因爲頁表的低12位存儲着一些flag,這些flag如下,比如T32

  • present的意思是頁是否是有效的,無效代表虛擬到物理地址之間的轉化無效,當訪問虛擬地址的時候就會page fault
  • protection :權限之類的,是否讀寫執行權限之類的。如果你訪問一段虛擬地址,頁表中是無法執行的權限,但是你想執行這段代碼就會出錯
  • reference: 引用之類的
  • cache: cache是否有效。有效就從cache取,無效從memory
  • dirty: 是否寫過,寫過就代表髒。在內存不夠時需要寫會處理的。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章