作者簡介:
Baron (csdn:代碼改變世界ctw),九年手機安全/SOC底層安全開發經驗。擅長trustzone/tee安全產品的設計和開發
(注:說明本文的介紹都是基于armv8-aarch64或armv9硬件架構)
在mmu未開啟階段,PC操作的都是物理地址執行程序,這樣看起來一切正常,沒啥問題。
例如:取指(到物理地址0x4000處取指)、譯碼、執行取指(物理地址0x4004處取指)、譯碼、執行取指(物理地址0x4008處取指)、譯碼、執行取指(物理地址0x400C處取指)、譯碼、執行
但是呢,假如程序在執行的過程中,你突然打開了MMU,那么會發生什么呢?比如在前面的示例中,就會出現,程序本來執行在0X4000、0x4004處好好的,而0x4004切好是enable_mmu指令,那么接下來PC將取值0x4008處地址的指令,由于此時MMU已經被打開了,那么0x4008會被當作虛擬地址,經過MMU翻譯...
經過MMU,那么就可能出現了兩種問題:一是虛擬地址0x4008所對應的頁表沒有建立,此時會產生prefetch abort;二是虛擬地址0x4008所對應的頁表已經建立了(例如指向物理0x9004處),那么此時cpu期望訪問物理地址0x4008處的,就被突然變成了訪問物理地址0x9004處了。
取指(到到物理地址0x4000處取指)、譯碼、執行取指(物理地址0x4004處取指)、譯碼、執行 -- 這條指令是開啟MMU取指(到虛擬地址0x4008處取指,經MMU單元后,要么是invalid,要么是0x9004)、譯碼、執行......
為了解決上述描述的問題,下面給出了兩種解決方案:第一種方案:在開啟MMU之前,我先對正在執行的這一小塊代碼建立個頁表(一一映射),那么此時的邏輯就變成了:
取指(到到物理地址0x4000處取指)、譯碼、執行取指(物理地址0x4004處取指)、譯碼、執行 -- 這條指令是開啟MMU取指(到虛擬地址0x4008處取指,經MMU單元后,物理地址依然是是0x4008)、譯碼、執行 -- 程序沒有跑飛......
第二種方案:在開啟MMU之前,我確實建立個頁表(不是一一映射哦,這是正常業務的頁表),此時的邏輯如下:
取指(到到物理地址0x4000處取指)、譯碼、執行取指(物理地址0x4004處取指)、譯碼、執行 -- 這條指令是開啟MMU取指,到虛擬地址0x4008處取指,經MMU單元時在頁表是找不到0x4008這個虛擬地址的(因為沒做map),所以會產生prefetch abort異常、而在異常代碼ERET返回時,正好返回到0xXXXX地址處,該地址是虛擬地址,正好MAP到0x4008物理地址,程序得到繼續執行,譯碼、執行 -- 程序很順利哦......
如果看到此處,您沒有看懂,沒關系,請看下列代碼示例:
程序在(1)處將 mmu_on_addr
鏈接地址(虛擬地址)寫入到了X30寄存器中程序在(2)處enable MMU,此時下一條指令取指,將被當作成虛擬地址,經過MMU翻譯,而對應的頁表中自然是沒有這個地址(物理地址被當作成的虛擬地址),所以此時將產生sync abort...程序在(3)處不會被執行,因為上面已經sync abort了
跳轉到sync abort后,代碼如下方所示,什么都沒干,直接ret返回了。
-
vector_entry sync_exception_sp_elx
-
ret
ret
指令返回的,PC自然是自動指向X30地址處,即 mmu_on_addr
鏈接地址(虛擬地址),程序繼續跑,一切步入正常流程...
原文標題:Baron:程序運行過程中突然打開MMU會怎么樣?
文章出處:【微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。
-
指令
+關注
關注
1文章
607瀏覽量
35714 -
程序
+關注
關注
117文章
3787瀏覽量
81049 -
MMU
+關注
關注
0文章
91瀏覽量
18291
原文標題:Baron:程序運行過程中突然打開MMU會怎么樣?
文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論