linux PCI设备驱动
-
1.PCI 簡介
- 1.1 PCI 引腳
為處理數據、尋址、接口控制、仲裁以及系統功能,PC接口作為目標設備的設備至少有47條引腳。作為總線主設備的設備至少有49條引腳。必要的引腳在左邊,任選的引腳在右邊
- 1.2 傳輸速率
Transparent upgrade from 32-bit data path at 33 MHz
(132 MB/s peak) to 64-bit data path at 33 MHz
(264 MB/s peak) and from 32-bit data path at 66 MHz
(264 MB/s peak) to 64-bit data path at 66 MHz
(528 MB/s peak).- 1.3 PCI 的配置空間
所有的PCI都設備必須實現PCI協議規定必需的配置寄存器,以便系統上電時利用這些寄存器的信息來進行系統配置。
配置空間頭區域及功能:
- 1.1 PCI 引腳
- 設備識別
- 設備控制
- 設備狀態
- 基址寄存器。系統初始化代碼在引導操作系統之前,必須建立一個統一的地址映射關系,以確定系統中有多少存儲器和IO控制器,它們需要占用多少地址空間,當確定這些信息后,系統初始化代碼便可以吧IO控制器映射到合理的地址空間并引導系統。為了做到這種映射與相應設備無關,在配置空間頭區域中安排了一組供映射時使用的基址寄存器。
基地址設置過程:
查看pci 配置寄存器內容:# hexdump /sys/bus/pci/devices/xxx/xxx/config 0000000 8086 2e30 0006 2090 0003 0600 0000 0000 0000010 0000 0000 0000 0000 0000 0000 0000 0000 0000020 0000 0000 0000 0000 0000 0000 1458 5000 0000030 0000 0000 00e0 0000 0000 0000 0000 0000 0000040 9001 fed1 0000 0000 4001 fed1 0000 0000 0000050 0000 0350 0009 0000 0000 0000 0000 0000 0000060 0005 e000 0000 0000 8001 fed1 0000 0000 0000070 0000 0000 0000 0000 0001 0000 0000 0000 0000080 0000 0000 0000 0000 0000 0000 0000 0000 0000090 1110 0011 0000 0000 03ff 0000 0a00 0079 00000a0 0020 0800 0000 7e00 0000 7de0 0000 7dd0 00000b0 8000 0000 0000 0000 0000 0000 0000 0000 00000c0 0000 0000 0000 0000 0000 0000 0000 0000 00000d0 0000 0000 0303 0000 6660 1366 aa55 aa55 00000e0 0009 610c 0b24 cfa7 9de2 812f 0000 0000 00000f0 0000 0000 0000 0000 0fa6 0005 0000 0000 0000100 0000 0000 0000 0000 0000 0000 0000 0000 * 0001000 -
2.PCI 驅動
- 2.1 注冊一個PCI設備驅動
為了被正確注冊到內核, 所有的 PCI 驅動必須創建的主結構是 struct pci_driver 結構.
這個結構包含許多函數回調和變量, 來描述 PCI 驅動給 PCI 核心. 這里是這個結構的一
個 PCI 驅動需要知道的成員:
總之, 為創建一個正確的 struct pci_driver 結構, 只有 4 個字段需要被初始化,一個PCI設備驅動的骨架如下:
static int probe(struct pci_dev *dev, const struct pci_device_id *id) {//... } static void remove(struct pci_dev *dev) {//... } static struct pci_driver pci_driver = { .name = "pci_skel", .id_table = ids, .probe = probe, .remove = remove, }; static int __init pci_skel_init(void) {return pci_register_driver(&pci_driver); } static void __exit pci_skel_exit(void) {pci_unregister_driver(&pci_driver); } module_init(pci_skel_init); module_exit(pci_skel_exit);- 2.2 probe 函數
pci_driver 的 probe()函數要完成 PCI 設備的初始化及其設備本身身份(字符、TTY、
網絡等)驅動的注冊。
- 2.3 常用的接口
- 2.1 注冊一個PCI設備驅動
-
3.小結
就跟USB、I2C、SPI、UART等常用接口一樣,PCI 也是一種通信接口,其最終的目的是實現數據交換,如果一個SPI接口的外設模塊要接在PCI接口上實現數據通信,那么中間需要加一個轉換芯片,如TIGER320.
PCI 設備的啟動分為兩個部分,第一部分是系統引導時,讀取配置寄存器信息(也就是常說的的配置空間)并確認好基址映射地址回寫到PCI設備的基址寄存器。第二部分是系統啟動后加載驅動,探測到該設備后,進行的初始化操作,如啟用PCI設備,申請IO空間,具體設備注冊,注冊中斷等。
參考資料:
1.《微機原理與接口技術》[劉立康]
2.《linux設備驅動程序》
總結
以上是生活随笔為你收集整理的linux PCI设备驱动的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 全球人工智能技术大会即将开幕
- 下一篇: 学JS必看-JavaScript数据结构