當我們寫一些外設驅動,或者核心模組,經常會使用ioremap函式來對映暫存器io位址,來訪問io空間,在ioremap函式的實現內部會對傳入的引數進行判斷,如果位址不屬於io空間,則會核心會報warnig。
從函式名字我們也可以看得出來,既然函式叫io remap,那麼對映的位址空間必須是io的實體地址,所以如果對映的位址落在了ram位址空間,核心就會報warning!如下面的log
核心報warning的日誌:
追溯一下**,讓我們找到真正的原因,先找到ioremap的定義,ioremap是一條巨集定義:(arch/arm64/include/asm/io.h)
#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(prot_device_ngnre))
__ioremap函式的定義如下,最終會呼叫__ioremap_caller函式:(arch/arm64/mm/ioremap.c)
void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot)
__ioremap_caller函式實現很短,注意其中的warn_on()函式,warn_on是核心常用的斷言,當條件為真時,會呼叫dump_stack列印堆疊,就會看到上面的一長串warning列印,相應的斷言還有bug_on。如果觸發了bug_on,核心一般會panic。但warn_on不會使核心崩潰。
static void __iomem *__ioremap_caller(phys_addr_t phys_addr, size_t size,
pgprot_t prot, void *caller)
return (void __iomem *)(offset + addr);
}
kernel用pfn_valid(__phys_to_pfn(phys_addr))來判斷該位址是否為乙個有效的系統ram位址,因為實體地址可以轉換成乙個有效的頁幀號。
---以上**摘自linux-4.9.30版本核心。
Linux核心中ioremap對映的透徹理解
幾乎每一種外設都是通過讀寫裝置上的暫存器來進行的,通常包括控制暫存器 狀態暫存器和資料暫存器三大類,外設的暫存器通常被連續地編址。根據cpu體系結構的不同,cpu對io埠的編址方式有兩種 典型地,如x86處理器為外設專門實現了乙個單獨的位址空間,稱為 i o位址空間 或者 i o埠空間 cpu通過專...
Linux核心中ioremap對映的透徹理解
幾乎每一種外設都是通過讀寫裝置上的暫存器來進行的,通常包括控制暫存器 狀態暫存器和資料暫存器三大類,外設的暫存器通常被連續地編址。根據cpu體系結構的不同,cpu對io埠的編址方式有兩種 典型地,如x86處理器為外設專門實現了乙個單獨的位址空間,稱為 i o位址空間 或者 i o埠空間 cpu通過專...
Linux核心中ioremap對映的透徹理解
幾乎每一種外設都是通過讀寫裝置上的暫存器來進行的,通常包括控制暫存器 狀態暫存器和資料暫存器三大類,外設的暫存器通常被連續地編址。根據cpu體系結構的不同,cpu對io埠的編址方式有兩種 典型地,如x86處理器為外設專門實現了乙個單獨的位址空間,稱為 i o位址空間 或者 i o埠空間 cpu通過專...