轉換分為兩種, 靜態和動態。
靜態就是下面那種,不過,靜態的地址轉換,還需要在kernel 初始化的時候作映射。?
動態映射是使用 ioremap 函數 。
- #define?SL2312_GPIO_BASE??0x4D000000????
- ????
- #define?IO_ADDRESS(x)??(((X)&0x0fffffff)+(((x)>>4)&0x0f000000)+0xf0000000)?????
- ????
- #define?GEMINI_GPIO_BASE1??IO_ADDRESS(SL2312_GPIO_BASE)?????
?
linux 有內存保護機制,無論是內核態還是用戶態。?
靜態映射 :是在物理地址上加一個偏移量, 所以虛擬地址是固定的。?
動態映射 :系統會生成一個虛擬地址對應到物理地址上,虛擬地址不是固定的。
linux在初始化運行時會根據一個map_desc的數組中的物理地址進行靜態映射,0x4D000000地址應該就是這樣映射的。
靜態映射的地址無須使用icoremap函數,只要知道在map_desc數組中物理地址與虛擬地址的移仿就可以了。?
至于驅動程序中關于物理地址是不是都要轉換呢,這個是當然的,linux是運行在虛擬地址的。
任何程序不能訪問物理地址,都必須轉換為物理地址才能訪問。只不過,在內核空間已經是轉換好了的(如前所述),可以隨便的訪問。?
動態映射是由Linux內核統一管理,當使用kmalloc(分配在內核空間)和malloc函數申請時,內核會找到一塊空余的物理內存,并在頁表中動態地添加一項其與虛擬地址對應的表項。?
靜態映射那應該就是LINUX在初始化階段讀取map_desc數組進行的地址映射,map_desc中包括了一對對的物理地址和虛擬地址的對應關系,這個可以根據硬件修改,其中的虛擬地址必須是內核空間的,例如,SDRAM的物理是0x30000000 那么可以將其映射為0xe0000000. 通過靜態映射后的地址一般之后就不會更改了的,除非你想辦法改掉。
?
注:以上均摘自論壇,僅供參考,不對的請指正,謝謝!