pci是什麼
pci—peripheral component interconnect,外圍裝置互**線。是一種廣泛採用的匯流排標準,它提供了許多優於其它匯流排標準(如eisa)的新特性,目前已經成為計算機系統中應用最為廣泛,並且最為通用的匯流排標準。
對於pci的一些具體介紹可以參考: pci具體介紹
一、和pci驅動程式相關的幾個資料結構
驅動程式總是離不開資料結構,在linux中,用資料結構來表示各色各樣的裝置或者其他的東西。因此,我們掌握裝置驅動程式的關鍵之一,就是對各種資料結構的理解和運用。
cpu 可以訪問pci裝置上的所有位址空間,其中i/o空間和儲存空間提供給裝置驅動程式使用,而配置空間則由linux核心中的pci初始化**使用,核心在 啟動時負責對所有pci裝置進行初始化,配置好所有的pci裝置,包括中斷號以及i/o基址,並在檔案/proc/pci中列出所有找到的pci裝置,以 及這些我裝置的引數和屬性。
我們並不需要去了解配置暫存器的所有位代表了什麼,有什麼含義。我們只要用三個或者五個pci暫存器去標識乙個裝置即可。通常,我們會選擇下面三個暫存器:
vendorid: 標識硬體製造商,是乙個16位的暫存器;
deviceid:裝置id,由製造商選擇,也是乙個16位的暫存器。一般與廠商id配對生成乙個唯一的32位硬體裝置識別符號;
class:每個外部裝置屬於某個類(class),也是乙個16位的暫存器。當某個驅動程式可支援多個相似的裝置,每個具有不同的簽名,但都屬於同乙個類,這時,就可以用class類對它們的外設進行識別。
下面的資料結構就是–pci_device_id。
struct pci_device_id
;
那現在問題又來了,我們前面說過,乙個驅動程式可以匹配乙個甚至多個裝置。那麼,此時我們又該如何呢?可以想到陣列,對吧。是的,不過這裡有點地方需要注意
staticstruct pci_device_id example_pci_tbl [
] __initdata =,}
;
不管你這裡匹配了多少裝置,記得最後乙個都是。
這裡還有兩個關於初始化該結構體的巨集,可以用來簡化相關的操作。
pci_device(vendor, device)
建立乙個僅和特定廠商及裝置id相匹配的struct pci_device_id。它把結構體的subvendor和subdevice設為pci_any_id。pci_any_id定義如下:
#define pci_any_id(~
0)
pci_device_class(device_class, device_class_mask)
建立乙個和特定pci類相匹配的struct pci_device_id。
2.pci_driver:
按照上面說的,你已經將你要匹配的裝置說明了,但這僅僅只是說明,核心如何去識別它們呢?那就要用到下面的資料結構了–pci_driver。
struct pci_driver
;
從上面的結構體定義可以看出,它的作用並不僅僅是識別裝置的id_table結構,還包括了檢測裝置的 函式probe( )和解除安裝裝置的函式remove( ):這種結構體。
/*
* the pci_dev structure is used to describe pci devices.
*/struct pci_dev
; struct pci_ats *ats;
/* address translation service */
#endif
};
由上面的定義可以知道,它詳細描述了乙個pci裝置幾乎所有的硬體資訊,包括廠商id、裝置id、各種資源等。
二、基本框架
上面將我們要用到的一些基本資訊都做了一些簡單的介紹。下面,我們就來看看pci驅動程式的乙個基本的框架,如何將這些東西進行整理成乙個程式。
staticstruct pci_device_id example_pci_tbl [
] __initdata =,}
;/* 對特定pci裝置進行描述的資料結構 */
struct example_pci
/* 中斷處理模組 */
staticvoid example_interrupt
(int irq,
void
*dev_id,struct pt_regs *regs)
/* 裝置檔案操作介面 */
staticstruct file_operations example_fops =
;/* 裝置模組資訊 */
staticstruct pci_driver example_pci_driver =
; staticint __init example_init_module
(void
) staticvoid __exit example_cleanup_module
(void
)/* 載入驅動程式模組入口 */
module_init
( example_init_module)
;/* 解除安裝驅動程式模組入口 */
module_exit
( example_cleanup_module)
;
上面這段**給出了乙個典型的pci裝置驅動程式的框架,是一種相對固定的模式。 Linux驅動學習 初識PCI驅動 二
寫在前面的話 我們從下面幾個方面來講述 一,初始化裝置模組 當linux 核心啟動並完成對所有 pci裝置進行掃瞄 登入和分配資源等初始化操作的同時,會建立起系統中所有 pci裝置的拓撲結構,此後當 pci驅動程式需要對裝置進行初始化時,一般都會呼叫如下的 static int init examp...
linux驅動子系統 PCI
pci子系統的關鍵概念包括 pci裝置 pci插槽 pci域 pci匯流排 pci橋 熱插拔控制器 pci裝置探測流程 linux啟動過程中會呼叫pci核心的探測函式進行pci裝置的探測,並建立起相關的拓撲關係以及記錄每個探測到的裝置的資訊 探測採用遞迴的方式從根控制器開始逐級往下探測,遇到橋控制器...
Linux的PCI驅動分析
1.關鍵資料結構 pci裝置上有三種位址空間 pci的i o空間 pci的儲存空間和pci的配置空間。cpu可以訪問pci裝置上的所有位址空間,其中i o空間和儲存空間提供給裝置驅動程式使用,而配置空間則由linux核心中的pci初始化 使用。核心在啟動時負責對所有pci裝置進行初始化,配置好所有的...