虚拟地址如何访问到物理地址
環(huán)境:32bit CPU
一、通過(guò)二級(jí)頁(yè)表映射的方式訪問物理地址
1、取一級(jí)頁(yè)表的基地址Abase1
2、取虛擬地址的前12bit[31:20]地址O1
3、計(jì)算得到新地址Apgd=(Abase1&0xFFFFF000)+O1,此地址是PGD頁(yè)表上的地址,取此地址中的數(shù)據(jù)Abase2
4、取虛擬地址的中間8bit[19:12]地址O2
5、計(jì)算得到新地址Apte=(Abase2&0xFFFFFF00)+O2,此地址是PTE頁(yè)表上的地址,取此地址中的數(shù)據(jù)Abase3
6、取虛擬地址的后12bit[11:0]地址O3
7、計(jì)算得到新地址Aphy=(Abase3&0xFFFFF000)+O3,此地址就是實(shí)實(shí)在在的物理地址
以上的計(jì)算和查找過(guò)程有MMU模塊實(shí)現(xiàn),同時(shí)會(huì)把映射信息存放在MMU中的TLB中,類似于cache,方便下次快速的查找。
二、疑問
1、一級(jí)頁(yè)表的基地址存放在什么地方?
2、如何找到存放在物理地址的信息?
三、分析問題
1、操作系統(tǒng)有個(gè)專門的結(jié)構(gòu)體負(fù)責(zé)進(jìn)程的內(nèi)存使用情況,task_struct里面的mm_struct
其中pgd保存的就是一級(jí)頁(yè)表的基地址。進(jìn)程切換時(shí),會(huì)把TTBRx寄存器(上圖所示)保存起來(lái),把下一個(gè)進(jìn)程的pgd內(nèi)容寫到TTBRx寄存器中。
2、寫段程序,找到存放信息的物理地址
2.1、內(nèi)核態(tài)代碼
根據(jù)上面所描述的頁(yè)表映射方式,查找到虛擬地址對(duì)應(yīng)的物理地址
需要在內(nèi)核態(tài)下面運(yùn)行,內(nèi)核態(tài)下可以獲取當(dāng)前進(jìn)程的PCB task_struct進(jìn)而獲取mm_struct內(nèi)存管理模塊
2.2、/dev/mem節(jié)點(diǎn)說(shuō)明
知道虛擬地址對(duì)應(yīng)的物理地址,我們就可以借助/dev/mem節(jié)點(diǎn)訪問對(duì)應(yīng)的物理地址查看是否是虛擬地址存放的數(shù)據(jù)。
/dev/mem是系統(tǒng)物理內(nèi)存的映像文件,這里的物理內(nèi)存是指我們插在內(nèi)存槽上的內(nèi)存條嗎?當(dāng)然是,但物理內(nèi)存不單單指內(nèi)存條。
物理內(nèi)存嚴(yán)格來(lái)講應(yīng)該是指 物理地址空間 ,內(nèi)存條只是映射到這個(gè)地址空間的一部分,其余的還有各種PCI設(shè)備,IO端口等。
我們可以從/proc/iomem中看到這個(gè)映射:
其中 內(nèi)存分配的物理地址是0x80000000~0x83FFFFFF 64M
事實(shí)上,它就是一個(gè)活著的Linux系統(tǒng)實(shí)時(shí)映像,所有的進(jìn)程task_struct結(jié)構(gòu)體,sock結(jié)構(gòu)體,sk_buff結(jié)構(gòu)體,進(jìn)程數(shù)據(jù)等等都在里面的某個(gè)位置:
如果能定位它們?cè)?dev/mem里的位置,我們就能得到系統(tǒng)中這些數(shù)據(jù)結(jié)構(gòu)的實(shí)時(shí)值,所謂的調(diào)試工具所做的也不過(guò)如此。其實(shí)我們?cè)谡{(diào)試內(nèi)核轉(zhuǎn)儲(chǔ)文件的時(shí)候,vmcore也是一個(gè)物理內(nèi)存映像,和/dev/mem不同的是,它是一具尸體。
無(wú)論是活體,還是尸體,均五臟俱全,分析它們的手段是一致。和靜態(tài)分析vmcore不同的是,/dev/mem是一個(gè)動(dòng)態(tài)的內(nèi)存映像,有時(shí)候借助它可以做一些正經(jīng)的事情。
2.3、應(yīng)用層獲取/dev/mem的映射
2.4、測(cè)試程序
測(cè)試程序: int main(int argc, char** argv) {int fd = -1;struct param_s param;char *buf = "Chinaxxxxx.\n";memset(¶m, 0x00, sizeof(struct ty_motor_param_s));fd = open("/dev/motor", O_RDWR);if (fd < 0) {printf("open error.\n");return 0;}printf("buf=0x%x", buf);param.addr = buf;ioctl(fd, IOCTL_SET, ¶m);close(fd);sleep(10);printf("buf=0x%x", buf);return 0; }2.5、實(shí)驗(yàn)開始
2.5.1、運(yùn)行2.4程序,通過(guò)ioctl運(yùn)行內(nèi)核代碼,執(zhí)行2.3程序get_phy_addr函數(shù),獲取物理地址。
2.5.2、通過(guò)傳入獲取到的物理地址,運(yùn)行2.2程序,打印物理地址的信息。
其中0x83e6573c是獲取的物理地址
ARM處理器小端存儲(chǔ)數(shù)據(jù),因此0x43 0x68 0x69 0x6e 剛好對(duì)應(yīng)著Chinaxxxxx中的Chin的Ascii碼值
2.6、擴(kuò)展
2.6.1、既然知道物理地址了,是不是可以修改物理地址里面的內(nèi)容?
2.6.2、打開2.3代碼的注釋 *(unsigned int *)(addr) = 0x6f6a6944;
2.6.3、再操作2.5中的步驟,發(fā)現(xiàn)原先的Chinaxxxxx被修改了
3、遇到的問題
3.1.1、2.3中的代碼mmap一直返回-1,錯(cuò)誤碼一直是1(errno 1 Operation not permitted)
3.1.2、解決方法
在.config文件中設(shè)置CONFIG_STRICT_DEVMEM is not set
正如上面描述的,通過(guò)獲取物理地址修改物理地址里面的數(shù)據(jù),這對(duì)系統(tǒng)來(lái)說(shuō)就毫無(wú)安全可言。因此內(nèi)核通過(guò)CONFIG_STRICT_DEVMEM配置項(xiàng)禁止內(nèi)存空間實(shí)現(xiàn)映射。
總結(jié)
以上是生活随笔為你收集整理的虚拟地址如何访问到物理地址的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 测试 Windows 8 中的 Metr
- 下一篇: [黑群晖经典教程] 一步一步建立自己的黑