ARM體系結構下面內存和i/o映射區別
(2)inb和outb:
在Linux設備驅動中,宜使用Linux內核提供的函數來訪問定位于I/O空間的端口,這些函數包括:
·
unsigned inb(unsigned port);
void outb(unsigned char byte, unsigned port);
·
unsigned inw(unsigned port);
void outw(unsigned short word, unsigned port);
·
unsigned inl(unsigned port);
void outl(unsigned longword, unsigned port);
·
void insb(unsigned port, void *addr, unsigned long count);
void outsb(unsigned port, void *addr, unsigned long count);
·
·
void insw(unsigned port, void *addr, unsigned long count);
void outsw(unsigned port, void *addr, unsigned long count);
·
void insl(unsigned port, void *addr, unsigned long count);
void outsl(unsigned port, void *addr, unsigned long count);
上述各函數中I/O端口號port的類型高度依賴于具體的硬件平臺,因此,只是寫出了unsigned。
(3)readb和writeb:
在設備的物理地址被映射到虛擬地址之后,盡管可以直接通過指針訪問這些地址,但是工程師宜使用Linux內核的如下一組函數來完成設備內存映射的虛擬地址的讀寫,這些函數包括:
·
unsigned int ioread8(void *addr);
unsigned int ioread16(void *addr);
unsigned int ioread32(void *addr);
與上述函數對應的較早版本的函數為(這些函數在Linux 2.6中仍然被支持):
unsigned readb(address);
unsigned readw(address);
unsigned readl(address);
·
void iowrite8(u8 value, void *addr);
void iowrite16(u16 value, void *addr);
void iowrite32(u32 value, void *addr);
與上述函數對應的較早版本的函數為(這些函數在Linux 2.6中仍然被支持):
void writeb(unsigned value, address);
void writew(unsigned value, address);
void writel(unsigned value, address);
(4)把I/O端口映射到“內存空間”:
void *ioport_map(unsigned long port, unsigned int count);
通過這個函數,可以把port開始的count個連續的I/O端口重映射為一段“內存空間”。然后就可以在其返回的地址上像訪問I/O內存一樣訪問這些I/O端口。當不再需要這種映射時,需要調用下面的函數來撤消:
void ioport_unmap(void *addr);
實際上,分析ioport_map()的源代碼可發現,所謂的映射到內存空間行為實際上是給開發人員制造的一個“假象”,并沒有映射到內核虛擬地址,僅僅是為了讓工程師可使用統一的I/O內存訪問接口訪問I/O端口。
評論