ioremap和vmalloc一樣,都會返回vmalloc區的虛擬位址,但是ioremap並不會分配任何實體記憶體,ioremap也需要建立新的頁表來訪問物理頁面。
ioremap擷取的虛擬位址空間需要使用iounmap來釋放。
ioremap主要用來映射裝置的實體記憶體到核心的虛擬位址空間,這樣,核心就可以通過這些虛擬位址空間訪問裝置記憶體。
使用ioremap需要注意幾點:
1. 盡量不要直接存取這些虛擬位址,使用專用的io操作函數可以增加移植性,當然有些特殊情況,比如android pmem是對實體記憶體進行的ioremap,所以可以直接存取記憶體
2. 有些情況下,可能不想讓系統cache發揮作用,這時要使用ioremap_nocache進行映射
今天偶然打了下ioremap返回的地址,居然是0x9c820000,而不是0xCxxx xxxx
一再確定列印地址代碼沒問題後,查了代碼也沒發現問題出在哪裡,最後dmesg找到了答案
Virtual kernel memory layout:
vector : 0xffff0000 - 0xffff1000 ( 4 kB)
fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB)
DMA : 0xf9e00000 - 0xffe00000 ( 96 MB)
vmalloc : 0x9c800000 - 0xf4000000 (1400 MB)
lowmem : 0x80000000 - 0x9c000000 ( 448 MB)
pkmap : 0x7fe00000 - 0x80000000 ( 2 MB)
modules : 0x7f000000 - 0x7fe00000 ( 14 MB)
.init : 0x80008000 - 0x8004e000 ( 280 kB)
.text : 0x8004e000 - 0x8086a000 (8304 kB)
.data : 0x80892000 - 0x808dfba0 ( 311 kB)
看來是把2G~4G定義為kernel空間,而ioremap的地址正好返回的是vmalloc的位址範圍內。