新聞中心
PCI(Peripheral Component Interconnect)總線是計(jì)算機(jī)中的一種總線接口標(biāo)準(zhǔn),它是連接計(jì)算機(jī)主板和外部設(shè)備的接口。而Linux是一種自由軟件操作系統(tǒng),它支持多種硬件體系結(jié)構(gòu),能夠運(yùn)行在各種設(shè)備上,包括PC、服務(wù)器、嵌入式設(shè)備等。在Linux系統(tǒng)中,PCI總線驅(qū)動(dòng)是一種非常重要的設(shè)備驅(qū)動(dòng)程序,它負(fù)責(zé)管理PCI總線,并控制PCI外設(shè)的工作。本文將詳細(xì)介紹Linux PCI總線驅(qū)動(dòng)的工作原理、使用方法以及開發(fā)流程等內(nèi)容。

連云港網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。創(chuàng)新互聯(lián)公司公司2013年成立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)公司。
一、PCI總線驅(qū)動(dòng)概述
PCI總線驅(qū)動(dòng)是Linux內(nèi)核中的一個(gè)模塊,它負(fù)責(zé)管理PCI總線上的所有設(shè)備,包括PCI橋、PCI設(shè)備等。這個(gè)模塊通常被稱為pci模塊,用戶可以通過pci模塊中提供的API來進(jìn)行PCI設(shè)備的控制和管理。
PCI總線驅(qū)動(dòng)的主要工作有以下幾個(gè)方面:
1. PCI設(shè)備的發(fā)現(xiàn)和枚舉:當(dāng)Linux系統(tǒng)啟動(dòng)時(shí),pci模塊會(huì)掃描PCI總線,尋找PCI設(shè)備,并分配資源。PCI設(shè)備的地址和IRQ等資源都是由pci模塊分配的。
2. PCI設(shè)備的初始化和控制:在PCI設(shè)備被發(fā)現(xiàn)后,pci模塊會(huì)執(zhí)行設(shè)備的初始化代碼,并將設(shè)備的信息保存在內(nèi)核數(shù)據(jù)結(jié)構(gòu)中,供其他驅(qū)動(dòng)程序使用。用戶程序可以通過pci模塊提供的API來控制PCI設(shè)備的工作,例如讀寫PCI設(shè)備的寄存器、發(fā)送控制命令等。
3. PCI設(shè)備的中斷處理:當(dāng)PCI設(shè)備有數(shù)據(jù)到達(dá)時(shí),它會(huì)產(chǎn)生中斷信號(hào),通知操作系統(tǒng)來處理數(shù)據(jù)。PCI總線驅(qū)動(dòng)會(huì)接收中斷信號(hào),并將其轉(zhuǎn)發(fā)給相應(yīng)的設(shè)備驅(qū)動(dòng)。設(shè)備驅(qū)動(dòng)在收到中斷信號(hào)后,就可以處理數(shù)據(jù),并發(fā)送回應(yīng)給PCI設(shè)備。
二、使用PCI總線驅(qū)動(dòng)
在Linux系統(tǒng)中,用戶可以使用pci模塊提供的api來訪問PCI設(shè)備。下面是一些常用的libpci API的介紹:
1. pci_enable_device():該API用于在PCI設(shè)備上啟用總線主人控制器。當(dāng)PCI設(shè)備被發(fā)現(xiàn)時(shí),它可能處于禁用狀態(tài),需要使用此函數(shù)來啟用它。
2. pci_request_regions():使用此API請(qǐng)求PCI設(shè)備的I/O端口和資源,訪問這些資源可以進(jìn)行讀寫操作。當(dāng)系統(tǒng)中同時(shí)存在多個(gè)設(shè)備時(shí),必須為每個(gè)設(shè)備分配不同的I/O端口和資源。
3. pci_alloc_consistent():使用此API為PCI設(shè)備分配連續(xù)的DMA內(nèi)存區(qū)域,通常用于數(shù)據(jù)傳輸。PCI設(shè)備使用DMA傳輸數(shù)據(jù),需要分配一段連續(xù)的物理內(nèi)存用于數(shù)據(jù)傳輸,否則將會(huì)出現(xiàn)內(nèi)存碎片等問題。
4. pci_irq_*():使用此API來管理PCI設(shè)備的中斷。PCI設(shè)備產(chǎn)生中斷時(shí),需要將中斷信號(hào)轉(zhuǎn)發(fā)給相應(yīng)的驅(qū)動(dòng)程序來處理。與IRQ相關(guān)的API包括pci_enable_msi()和pci_request_irq()。
5. pci_read_config_*()和pci_write_config_*():使用此API訪問PCI設(shè)備的配置空間,這個(gè)配置空間是一個(gè)硬件專用寄存器,用于存儲(chǔ)PCI設(shè)備的各種配置信息,例如廠商ID、設(shè)備ID、IRQ等信息。
三、開發(fā)PCI驅(qū)動(dòng)的流程
在Linux系統(tǒng)中,開發(fā)PCI驅(qū)動(dòng)的流程主要包括以下步驟:
1. 設(shè)計(jì)PCI設(shè)備:這個(gè)過程需要我們?cè)O(shè)計(jì)PCI設(shè)備的硬件電路、定義各種寄存器和接口等。根據(jù)設(shè)計(jì)的PCI設(shè)備硬件電路來編寫相應(yīng)的硬件描述文件,例如Verilog或VHDL等。
2. 編寫驅(qū)動(dòng)程序:驅(qū)動(dòng)程序是連接硬件設(shè)備和操作系統(tǒng)的中間件,它負(fù)責(zé)管理硬件設(shè)備和操作系統(tǒng)之間的通信。驅(qū)動(dòng)程序通常包括一個(gè)設(shè)備驅(qū)動(dòng)和一個(gè)總線驅(qū)動(dòng)。設(shè)備驅(qū)動(dòng)用于處理PCI設(shè)備的特定功能,總線驅(qū)動(dòng)則用于管理PCI總線和PCI設(shè)備。驅(qū)動(dòng)程序通常使用C語言編寫。
3. 編譯驅(qū)動(dòng)程序:驅(qū)動(dòng)程序一般是一個(gè)內(nèi)核模塊,需要將其編譯成共享庫,可以使用make命令進(jìn)行編譯。
4. 安裝驅(qū)動(dòng)程序:使用inod命令將驅(qū)動(dòng)程序加載到Linux內(nèi)核中。驅(qū)動(dòng)程序會(huì)根據(jù)其規(guī)格進(jìn)行配置,可以在/etc/modprobe.conf文件中進(jìn)行配置。
5. 測試驅(qū)動(dòng)程序:在驅(qū)動(dòng)程序加載后,需要進(jìn)行測試以確保其正常工作。測試過程包括讀寫內(nèi)存、發(fā)送命令、觀察輸出等操作。
在Linux系統(tǒng)中,PCI總線驅(qū)動(dòng)是連接計(jì)算機(jī)主板和外部設(shè)備的關(guān)鍵技術(shù)之一。它負(fù)責(zé)管理PCI總線和PCI設(shè)備,控制數(shù)據(jù)傳輸和中斷處理。本文簡要介紹了PCI總線驅(qū)動(dòng)的工作原理、使用方法和開發(fā)流程等內(nèi)容,希望對(duì)讀者有所幫助。
相關(guān)問題拓展閱讀:
- 如何讓linux重新枚舉pci設(shè)備
如何讓linux重新枚舉pci設(shè)備
在Linux下,lspci可以枚舉所有PCI設(shè)鎮(zhèn)梁備。它是通過讀取PCI配置空間(PCI Configuration Space)信息來實(shí)現(xiàn)PCI設(shè)備的枚舉的。這里,我通過兩種方式來簡單的模擬一下lspci的功能。一種是通過PCI總線的CF8和CFC端口來枚舉(參考PCI總線規(guī)范);另一種是利用proc filesystem。
方法一:這種方法需要對(duì)端口進(jìn)行操作,在Linux下,普通應(yīng)用程序沒有權(quán)限讀寫I/O 端口,需圓仿要通過iopl或ioperm來提升權(quán)限,我的代碼里面使用iopl。
view plaincopyprint?
/*
* Enum all pci device via the PCI config register(CF8 and CFC).
*/
#include
#include
#include
#include
#define PCI_MAX_BUS 255 /* 8 bits (0 ~ 255) */
#define PCI_MAX_DEV 31 /* 5 bits (0 ~ 31) */
#define PCI_MAX_FUN 7 /* 3 bits (0 ~ 7) */
#define CONFIG_ADDRESS 0xCF8
#define CONFIG_DATA 0xCFC
#define PCICFG_REG_VID 0x00 /* Vendor id, 2 bytes */
#define PCICFG_REG_DID 0x02 /* Device id, 2 bytes */
#define PCICFG_REG_CMD 0x04 /* Command register, 2 bytes */
#define PCICFG_REG_STAT 0x06 /* Status register, 2 bytes */
#define PCICFG_REG_RID 0x08 /* Revision id, 1 byte */
void list_pci_devices()
{
unsigned int bus, dev, fun;
unsigned int addr, data;
//printf(“BB:DD:FF VID:DID\n”);
for (bus = 0; bus >16);
addr = 0xL | (bus
#include
#include
#include
#include
#include
#define PCI_MAX_BUS 255 /* 8 bits (0 ~ 255) */
#define PCI_MAX_DEV 31 /* 5 bits (0 ~ 31) */
#define PCI_MAX_FUN 7 /* 3 bits (0 ~ 7) */
/*
* PCI Configuration Header offsets
*/
#define PCICFG_REG_VID 0x00 /* Vendor id, 2 bytes */
#define PCICFG_REG_DID 0x02 /* Device id, 2 bytes */
#define PCICFG_REG_CMD 0x04 /* Command register, 2 bytes */
#define PCICFG_REG_STAT 0x06 /* Status register, 2 bytes */
#define PCICFG_REG_RID 0x08 /* Revision id, 1 byte */
#define PCICFG_REG_PROG_INTF 0x09 /* Programming interface code, 1 byte */
#define PCICFG_REG_SUBCLASS 0x0A /* Sub-class code, 1 byte */
#define PCICFG_REG_BASCLASS 0x0B /* Base class code, 1 byte */
#define PCICFG_REG_CACHE_LINESZ 0x0C /* Cache line size, 1 byte */
#define PCICFG_REG_LATENCY_TIMER 0x0D /* Latency timer, 1 byte */
#define PCICFG_REG_HEADER_TYPE 0x0E /* Header type, 1 byte */
#define PCICFG_REG_BIST 0x0F /* Builtin self test, 1 byte */
#define PCICFG_REG_BAR0 0x10 /* Base addr register 0, 4 bytes */
#define PCICFG_REG_BAR1 0x14 /* Base addr register 1, 4 bytes */
#define PCICFG_REG_BAR2 0x18 /* Base addr register 2, 4 bytes */
#define PCICFG_REG_BAR3 0x1C /* Base addr register 3, 4 bytes */
#define PCICFG_REG_BAR4 0x20 /* Base addr register 4, 4 bytes */
#define PCICFG_REG_BAR5 0x24 /* Base addr register 5, 4 bytes */
#define PCICFG_REG_CIS 0x28 /* Cardbus CIS Pointer */
#define PCICFG_REG_SVID 0x2C /* Subsystem Vendor ID, 2 bytes */
#define PCICFG_REG_SDID 0x2E /* Subsystem ID, 2 bytes */
#define PCICFG_REG_ROMBAR 0x30 /* ROM base register, 4 bytes */
#define PCICFG_REG_CAPPTR 0x34 /* Capabilities pointer, 1 byte */
#define PCICFG_REG_INT_LINE 0x3C /* Interrupt line, 1 byte */
#define PCICFG_REG_INT_PIN 0x3D /* Interrupt pin, 1 byte */
#define PCICFG_REG_MIN_GNT 0x3E /* Minimum grant, 1 byte */
#define PCICFG_REG_MAX_LAT 0x3F /* Maximum lat, 1 byte */
void list_pci_devices()
{
unsigned int bus, dev, fun;
//printf(“BB:DD:FF VID:DID(RID)\n”);
for (bus = 0; bus >16;
printf(“%02X:%02X:%02X”, bus, dev, fun);
if (rid > 0) {
printf(” %04X:%04X (rev %02X)\n”, vid, did, rid);
} else {
printf(” %04X:%04X\n”, vid, did);
}
}
} // end func
} // end device
} // end bus
}
int main(int argc, char **argv)
{
list_pci_devices();
return 0;
}
這兩種方法各有優(yōu)缺點(diǎn),之一種方法方便移植到其他OS,第二種就只適用于Linux。但是,之一種方法需要對(duì)I/O port進(jìn)行直接操作。第二種就不需要。
注意:執(zhí)行這兩段代碼時(shí),需要超級(jí)用戶(root) 權(quán)限。
補(bǔ)充:今天在枚舉 Westmere-EP Processor(Intel Xeon Processor 5500 Series(Nehalem-EP))的 IMC(Integrated Memory Controller)時(shí)發(fā)現(xiàn)一個(gè)問題。lspci無法枚舉到IMC設(shè)備。Westmere-EP 是 Intel 新的處理器架構(gòu)。和以往的CPU不一樣,它把Memory Controller集成到了CPU里面。IMC控制器被映射到了PCI總線上,Bus Number 是0xFE~0xFF,procfs(/proc/bus/pci/)下沒有這幾個(gè)設(shè)備。但是,通過 CF8/CFC 端口可以枚舉到這些設(shè)備。
3. 這段代碼是在驅(qū)動(dòng)中可以用來查找特定的pci device,并且返回一個(gè)pci_dev的結(jié)構(gòu)體變量。通過這樣一個(gè)struct變量,內(nèi)核提供的接口函數(shù)可以直接套用,如pci_read_config_word(),pci_write_config_word()等。
view plaincopyprint?
void list_pci_device()
{
struct pci_dev *dev;
struct pci_bus *bus,*childbus;
list_for_each_entry(bus, &pci_root_buses, node) { //globle pci_root_buses in pci.h
list_for_each_entry(dev, &bus->devices, bus_list) { // for bus 0
printk(“%02X:%02X:%02X %04X:%04X\n”,dev->bus->number,dev->devfn >> 3, dev->devfn & 0x07,dev->vendor,dev->device);
}
list_for_each_entry(childbus, &bus->children,node) { // for bus 1,2,3,…
list_for_each_entry(dev, &childbus->devices, bus_list) {
printk(“%02X:%02X:%02X %04X:%04X\n”,dev->bus->number,dev->devfn >> 3, dev->devfn & 0x07,dev->vendor,dev->device);
}
}
linux pci 總線驅(qū)動(dòng)的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于linux pci 總線驅(qū)動(dòng),Linux PCI 總線驅(qū)動(dòng)詳解,如何讓linux重新枚舉pci設(shè)備的信息別忘了在本站進(jìn)行查找喔。
成都網(wǎng)站營銷推廣找創(chuàng)新互聯(lián),全國分站站群網(wǎng)站搭建更好做SEO營銷。
創(chuàng)新互聯(lián)(www.cdcxhl.com)四川成都IDC基礎(chǔ)服務(wù)商,價(jià)格厚道。提供成都服務(wù)器托管租用、綿陽服務(wù)器租用托管、重慶服務(wù)器托管租用、貴陽服務(wù)器機(jī)房服務(wù)器托管租用。
標(biāo)題名稱:Linux PCI 總線驅(qū)動(dòng)詳解 (linux pci 總線驅(qū)動(dòng))
標(biāo)題路徑:http://m.fisionsoft.com.cn/article/dhpedji.html


咨詢
建站咨詢
