1)cat /proc/iomem看到的內(nèi)容:
IO memory空間的地址資源分配情況,以樹狀結(jié)構(gòu)顯示。
request_mem_region
ioremap
2)cat /proc/ioports看到的內(nèi)容
IO port空間的地址資源分配情況,以樹狀結(jié)構(gòu)顯示。[源于x86平臺的設(shè)計思想,目前基本不用了] request_region
ioremap
# define __iomem __attribute__((noderef, address_space(2)))
void __iomem *fpga_vbase;
__iomem是linux2.6.9內(nèi)核中加入的特性。是用來個表示指針是指向一個I/O的內(nèi)存空間。主要是為了驅(qū)動程序的通用性考慮。由于不同的CPU體系結(jié)構(gòu)對I/O空間的表示可能不同。當使用__iomem時,編譯器會忽略對變量的檢查(因為用的是void __iomem)。若要對它進行檢查,當__iomem的指針和正常的指針混用時,就會發(fā)出一些警告。
include/linux/compiler.h , make C=1 時會有檢查,C=0
則無任何作用。 $ grep -RIn 'define __iomem' include/linux #ifdef __CHECKER__
# define __user __attribute__((noderef, address_space(1))) # define __kernel /* default address space */ # define __safe __attribute__((safe)) # define __force __attribute__((force)) # define __nocast __attribute__((nocast)) # define __iomem __attribute__((noderef, address_space(2))) # define __acquires(x) __attribute__((context(0,1))) # define __releases(x) __attribute__((context(1,0))) # define __acquire(x) __context__(1) # define __release(x) __context__(-1) # define __cond_lock(x) ((x) ? ({ __context__(1); 1; }) : 0) extern void __chk_user_ptr(void __user *); extern void __chk_io_ptr(void __iomem *); #else # define __user # define __kernel # define __safe # define __force # define __nocast # define __iomem # define __chk_user_ptr(x) (void)0 # define __chk_io_ptr(x) (void)0 # define __builtin_warning(x, y...) (1) # define __acquires(x) # define __releases(x) # define __acquire(x) (void)0 # define __release(x) (void)0 # define __cond_lock(x) (x) #endif 概念性的東西:
幾乎每一種外設(shè)都是通過讀寫設(shè)備上的寄存器來進行的。外設(shè)寄存器也稱為“I/O端口”,通常包括:控制寄存器、狀態(tài)寄存器和數(shù)據(jù)寄存器三大類,而且一個外設(shè)的寄存器通常被連續(xù)地編址。CPU對外設(shè)IO端口物理地址的編址方式有兩種:一種是I/O映射方式(I/O-mapped),另一種是內(nèi)存映射方式(Memory-mapped)。而具體采用哪一種則取決于CPU的體系結(jié)構(gòu)。 有些體系結(jié)構(gòu)的CPU(如,PowerPC、m68k等)通常只實現(xiàn)一個物理地址空間(RAM)。在這種情況下,外設(shè)I/O端口的物理地址就被映射到CPU的單一物理地址空間中,而成為內(nèi)存的一部分。此時,CPU可象訪問一個內(nèi)存單元那樣訪問外設(shè)I/O端口,而無需設(shè)立專門的外設(shè)I/O指令。這就是所謂的“內(nèi)存映射方式”(Memory-mapped)。 而另外一些體系結(jié)構(gòu)的CPU(典型地如X86)則為外設(shè)專門實現(xiàn)了一個單獨地地址空間,稱為“I/O地址空間”或“I/O端口空間”。這是個和CPU地RAM物理地址空間不同的地址空間,任何外設(shè)的I/O端口均在這一空間中進行編址。CPU通過設(shè)立專門的I/O指令(如X86的IN和OUT指令)來訪問這一空間中的地址單元(也即I/O端口)。這就是所謂的“I/O映射方式”(I/O-mapped)。和RAM物理地址空間相比,I/O地址空間通常都比較小,如x86 CPU的I/O空間就只有64KB(0-0xffff)。這是“I/O映射方式”的一個主要缺點。
Linux設(shè)計了一個通用的數(shù)據(jù)結(jié)構(gòu)resource來描述各種I/O資源(如:I/O端口、外設(shè)內(nèi)存、DMA和IRQ等)。該結(jié)構(gòu)定義在include/linux/ioport.h頭文件中。
Linux是以一種倒置的樹形結(jié)構(gòu)來管理每一類I/O資源(如:I/O端口、外設(shè)內(nèi)存、DMA和IRQ)的。每一類I/O資源都對應(yīng)有一顆倒置的資源樹,樹中的每一個節(jié)點都是個resource結(jié)構(gòu),而樹的根結(jié)點root則描述了該類資源的整個資源空間。
基于上述這個思想,Linux將基于I/O映射方式的I/O端口和基于內(nèi)存映射方式的I/O端口資源統(tǒng)稱為“I/O區(qū)域”(I/O Region)。
參考:
linux/kernel/resource.c
include/linux/Ioport.h |
|