--------------------------------------
linux設計了乙個通用的資料結構resource來描述各種i/o資源(如:i/o埠、外設記憶體、dma和irq等)。該結構定義在include/linux/ioport.h標頭檔案中:
struct
resource
;linux對i/o資源的管理
--------------------------------------
linux是以一種倒置的樹形結構來管理每一類i/o資源(如:i/o埠、外設記憶體、dma和irq)的。每一類i/o資源都對應有一顆倒置的資源樹,樹中的每乙個節點都是乙個resource結構,而樹的根結點root則描述了該類資源的整個資源空間。
基於上述這個思想,linux在kernel/resource.c檔案中實現了對資源的申請、釋放及查詢等操作。
資源的申請:
request_resource()
資源的釋放: release_resource()
尋找可用資源: -
-find_resource()
分配資源: allocate_resource()
管理i/o region資源
--------------------------------------
linux將基於i/o對映方式的i/o埠和基於記憶體對映方式的i/o埠資源統稱為「i/o區域」(i/o region)。i/o region仍然是一種i/o資源,因此它仍然可以用resource結構型別來描述。下面我們就來看看linux是如何管理i/o region的。
i/o region的分配: __request_region()
i/o region的釋放: __release_region()
檢查指定的i/o region是否已被占用: __check_region()
管理i/o埠資源
linux在kernel/resource.c檔案中定義了全域性變數ioport_resource和iomem_resource,來分別描述基於i/o對映方式的整個i/o埠空間和基於記憶體對映方式的i/o記憶體資源空間(包括i/o埠和外設記憶體)。其定義如下:
struct resourceioport_resource = ;
struct resourceiomem_resource = ;
其中,巨集io_space_limit表示整個i/o空間的大小,對於x86平台而言,它是0xffff(定義在include/asm-i386/io.h標頭檔案中)。顯然,i/o記憶體空間的大小是4gb。
對i/o埠空間的操作:
基於i/o region的操作函式__***_region(),linux在標頭檔案include/linux/ioport.h中定義了三個對i/o埠空間進行操作的介面:
request_region() 請求在i/o埠空間中分配指定範圍的i/o埠資源。
check_region() 檢查i/o埠空間中的指定i/o埠資源是否已被占用。
release_region() 釋放i/o埠空間中的指定i/o埠資源。
對i/o記憶體資源的操作:
基於i/o region的操作函式__***_region(),linux在標頭檔案include/linux/ioport.h中定義了三個對i/o記憶體資源進行操作的介面:
request_mem_region() 請求分配指定的i/o記憶體資源。
check_mem_region() 檢查指定的i/o記憶體資源是否已被占用。
release_mem_region() 釋放指定的i/o記憶體資源。
訪問i/o埠空間
--------------------------------------
在驅動程式請求了i/o埠空間中的埠資源後,它就可以通過cpu的io指定來讀寫這些i/o埠了。在讀寫i/o埠時要注意的一點就是,大多數平台都區分8位、16位和32位的埠,也即要注意i/o埠的寬度。
inb() outb() inw() outw() inl() outl()
unsigned char inb(unsigned port);
port引數指定i/o埠空間中的埠位址。在大多數平台上(如x86)它都是unsigned short型別的,其它的一些平台上則是unsigned int型別的。顯然,埠位址的型別是由i/o埠空間的大小來決定的。
對i/o埠的字串操作
除了上述這些「單發」(single-shot)的i/o操作外,某些cpu也支援對某個i/o埠進行連續的讀寫操作,也即對單個i/o埠讀或寫一系列位元組、字或32位整數,這就是所謂的「字串i/o指令」(string instruction)。這種指令在速度上顯然要比用迴圈來實現同樣的功能要快得多。
insb() outsb() insw() outw() insl() outsl()
pausing i/o
在一些平台上(典型地如x86),對於老式匯流排(如isa)上的慢速外設來說,如果cpu讀寫其i/o埠的速度太快,那就可能會發生丟失資料的現象。對於這個問題的解決方法就是在兩次連續的i/o操作之間插入一段微小的時延,以便等待慢速外設。這就是所謂的「pausing i/o」。
對於pausing i/o,linux也在io.h標頭檔案中定義了它的i/o讀寫函式,而且都以***_p命名,比如:inb_p()、outb_p()等等。
訪問i/o記憶體資源
(i/o memory)
linux在io.h標頭檔案中宣告了函式ioremap()
,用來將i/o記憶體資源的物理位址對映到核心虛位址空間(3gb-4gb)中
對於x86體系結構ioremap()定義在/usr/src/linux-2.6.21.5/include/asm-i386/io.h中
讀寫i/o記憶體資源
在將i/o記憶體資源的物理位址對映成核心虛位址後,理論上講我們就可以象讀寫ram那樣直接讀寫i/o記憶體資源了。但是,由於在某些平台上,對 i/o記憶體和系統記憶體有不同的訪問處理,因此為了確保跨平台的相容性,linux實現了一系列讀寫i/o記憶體資源的函式,這些函式在不同的平台上有不同的實現。但在x86平台上,讀寫i/o記憶體與讀寫ram無任何差別。如下所示(include/asm-i386/io.h):
readb() readw() readl()
writeb() writew() writel()
memset_io() memcpy_fromio() memcpytoio()
顯然,在x86平台上訪問i/o記憶體資源與訪問系統主存ram是無差別的。但是為了保證驅動程式的跨平台的可移植性,我們應該使用上面的函式來訪問i/o記憶體資源,而不應該通過指向核心虛位址的指標來訪問。
Linux對I O埠資源的管理 ZZ
linux設計了乙個通用的資料結構resource來描述各種i o資源 如 i o埠 外設記憶體 dma和irq等 該結構定義在include linux ioport.h標頭檔案中 struct resource linux對i o資源的管理 linux是以一種倒置的樹形結構來管理每一類i o資源...
Linux 對 IO 埠的操作
1。在裝置開啟或者驅動模組被載入時,申請i o埠區域 request region 2。之後使用inb outb 等函式對i o埠操作 3。在裝置被關閉或者解除安裝時,釋放i o埠範圍 release region 1。在裝置開啟或者驅動模組被載入時,申請i o埠區域並且使用ioport map 對...
VB對I O埠操作
一 i o埠介紹 訊號採集與控制是工業控制的最重要組成部分。在工業控制中,通常採集到的訊號有兩類 一類是電壓或電流模擬訊號 另一類是開關量或數字脈衝量 開關量 脈衝量都屬於數碼訊號 通常檢測出的訊號如果是模擬量的話,必須經過放大 變換變為電壓0 10伏或電流0 10ma,這些模擬量必須經過模 數轉換...