參考:
很多預設的外設i/o資源是不在linux核心空間中,如sram、硬體暫存器,如果要訪問這些資源,就必須將它位址對映到核心空間。linux核心空間訪問外設i/o資源有兩種方式:動態對映(ioremap)和靜態對映(map_desc)。
一、動態對映
動態對映方式接觸應該比較多,即通過核心提供的ioremap函式動態建立外設i/o記憶體虛擬位址的對映表,從而可以再核心空間中訪問這段i/o資源。ioremap巨集定義在include/asm-generic/io.h
舉乙個ad的例子,通過上面操作就可以訪問經過ioremap對映後的虛擬空間。
static void __iomem *base_addr;
base_addr=ioremap(s3c2410_pa_adc,0x20);
ioread32(base_addr+s3c2410_adcdat0);
二、靜態對映
核心提供在系統啟動時通過map_desc結構體靜態建立i/o資源到核心位址空間的線性對映表。程式設計師可以自己定義該i/o記憶體資源對映後虛擬位址。建立好靜態對映表後,在核心驅動訪問i/o資源是無需ioremap動態對映,可以直接通過靜態對映後的i/o虛擬位址訪問。
核心通過machine_desc結構體來控制系統架構初始化,它包括map_io, init_irq, init_machine以及phys_io , timer成員等,結構體如下:
struct machine_desc
展開後等價於:
static struct map_desc s3c2410_iodesc __initdata = {
.virtual = (unsigned long)s3c24xx_va_gpio),
.pfn = __phys_to_pfn(s3c24xx_pa_ gpio),
.length = s3c24xx_sz_ gpio,
.type = mt_device
s3c24xx_va_gpio、s3c24xx_pa_ gpio、s3c24xx_sz_ gpio定義以及其他資源定義:
arch/arm/mach-s3c2410/include/mach/map.h它引用下面兩個檔案
arch/arm/plat-s3c/include/plat/map_base.h
arch/arm/plat-s3c24xx/include/plat/map.h
在map_base.h中定義了虛擬位址對映換算:這裡就是一種線性偏移關係,即s3c2410建立的i/o靜態對映表會被對映到0xf4000000之後。(這個線性偏移值可以改,也可以你自己在virtual成員裡手動定義乙個值,只要不和其他i/o資源對映位址衝突)
#define s3c_addr_base (0xf4000000)
#ifndef __assembly__
#define s3c_addr(x) ((void __iomem __force *)s3c_addr_base + (x))
#else
#define s3c_addr(x) (s3c_addr_base + (x))
#endif
經過上面對映後的虛擬位址就可以直接訪問,s3c_addr的線性偏移只是s3c2410平台的一種做法,很多其他arm平台採用了通用的io_address巨集來計算實體地址到虛擬位址之前的偏移。到此,我們知道了通過map_desc結構體建立i/o記憶體資源靜態對映表的原理。總結一下發現其實過程很簡單,一通過定義map_desc結構體建立靜態對映表,二在核心中通過建立對映後虛擬位址訪問該i/o資源。
補充一點說明,在timer驅動中暫存器能直接訪問,而adc驅動需要ioremap對映,原因是timer在系統中已經做好靜態對映。並不是系統所有暫存器資源都做了靜態對映,所以使用時要注意。
Linux 核心訪問外設IO資源的方式
首先介紹一下i o埠和i o記憶體。1.i o埠 當乙個暫存器或記憶體位於i o空間時,稱其為i o埠。2.i o記憶體 當乙個暫存器或記憶體位於記憶體空間時,稱其為i o記憶體。再來看一下i o暫存器和常規記憶體的區別 i o暫存器具有邊際效應 side effect 而記憶體操作則沒有,記憶體寫...
Linux核心訪問外設I O資源的方式
linux核心訪問外設i o資源的方式 我們知道缺省外設i o資源是不在linux核心空間中的 如sram或硬體介面暫存器等 若需要訪問該外設i o資源,必須先將其位址對映到核心空間中來,然後才能在核心空間中訪問它。linux核心訪問外設i o記憶體資源的方式有兩種 動態對映 ioremap 和靜態...
外設I O資源的訪問方式
華清遠見嵌入式學院 講師。我們知道缺省外設i o資源是不在linux核心空間中的 如sram或硬體介面暫存器等 若需要訪問該外設i o資源,必須先將其位址對映到核心空間中來,然後才能在核心空間中訪問它。linux核心訪問外設i o記憶體資源的方式有兩種 動態對映 ioremap 和靜態對映 map ...