一、PCI簡(jiǎn)單介紹
???? PCI是一種外設(shè)總線規(guī)范。我們先來(lái)看一下什么是總線:總線是一種傳輸信號(hào)的路徑或信道。典型情況是,總線是連接于一個(gè)或多個(gè)導(dǎo)體的電氣連線,總 線上連接的全部設(shè)備可在同一時(shí)間收到全部的傳輸內(nèi)容。總線由電氣接口和編程接口組成。本文討論Linux 下的設(shè)備驅(qū)動(dòng),所以,重點(diǎn)關(guān)注編程接口。
???? PCI是Peripheral Component Interconnect(外圍設(shè)備互聯(lián))的簡(jiǎn)稱,是普遍使用在桌面及更大型的計(jì)算機(jī)上的外 設(shè)總線。PCI架構(gòu)被設(shè)計(jì)為ISA標(biāo)準(zhǔn)的替代品,它有三個(gè)主要目標(biāo):獲得在計(jì)算機(jī)和外設(shè)之間數(shù)據(jù)傳輸時(shí)更好的性能;盡可能的平臺(tái)無(wú)關(guān);簡(jiǎn)化往系統(tǒng)中加入和 刪除外設(shè)的工作。
二、PCI尋址
???? 從如今開(kāi)始,我想盡可能通過(guò)一些實(shí)際的樣例來(lái)說(shuō)明問(wèn)題,而降低理論方面的問(wèn)題的描寫敘述,由于,相關(guān)的理論的東西,能夠在其他地方找到。
???? 我們先來(lái)看一個(gè)樣例,我的電腦裝有1G的RAM,1G以后的物理內(nèi)存地址空間都是外部設(shè)備IO在系統(tǒng)內(nèi)存地址空間上的映射。 /proc/iomem描寫敘述了系統(tǒng)中全部的設(shè)備I/O在內(nèi)存地址空間上的映射。我們來(lái)看地址從1G開(kāi)始的第一個(gè)設(shè)備在/proc/iomem中是怎樣描寫敘述 的:
???????????? 40000000-400003ff : 0000:00:1f.1
???? 這是一個(gè)PCI設(shè)備,40000000-400003ff是它所映射的內(nèi)存地址空間,占領(lǐng)了內(nèi)存地址空間的1024 bytes的位置,而 0000:00:1f.1則是一個(gè)PCI外設(shè)的地址,它以冒號(hào)和逗號(hào)分隔為4個(gè)部分,第一個(gè)16位表示域,第二個(gè)8位表示一個(gè)總線編號(hào),第三個(gè)5位表示一 個(gè)設(shè)備號(hào),最后是3位,表示功能號(hào)。
???? 由于PCI規(guī)范同意單個(gè)系統(tǒng)擁有高達(dá)256個(gè)總線,所以總線編號(hào)是8位。但對(duì)于大型系統(tǒng)而言,這是不夠的,所以,引入了域的概念,每一個(gè) PCI域能夠擁有最多256個(gè)總線,每一個(gè)總線上可支持32個(gè)設(shè)備,所以設(shè)備號(hào)是5位,而每一個(gè)設(shè)備上最多可有8種功能,所以功能號(hào)是3位。由此,我們能夠得 出上述的PCI設(shè)備的地址是0號(hào)域0號(hào)總線上的31號(hào)設(shè)備上的1號(hào)功能。
???? 那上述的這個(gè)PCI設(shè)備究竟是什么呢?以下是我的電腦上的lspci命令的輸出:
???? 00:00.0 Host bridge: Intel Corporation 82845 845 (Brookdale) Chipset Host Bridge (rev 04)
???? 00:01.0 PCI bridge: Intel Corporation 82845 845 (Brookdale) Chipset AGP Bridge(rev 04)
???? 00:1d.0 USB Controller: Intel Corporation 82801CA/CAM USB (Hub #1) (rev 02)
???? 00:1d.1 USB Controller: Intel Corporation 82801CA/CAM USB (Hub #2) (rev 02)
???? 00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev 42)
???? 00:1f.0 ISA bridge: Intel Corporation 82801CAM ISA Bridge (LPC) (rev 02)
???? 00:1f.1 IDE interface: Intel Corporation 82801CAM IDE U100 (rev 02)
???? 00:1f.3 SMBus: Intel Corporation 82801CA/CAM SMBus Controller (rev 02)
???? 00:1f.5 Multimedia audio controller:Intel Corporation 82801CA/CAM AC'97 Audio Controller (rev 02)
???? 00:1f.6 Modem: Intel Corporation 82801CA/CAM AC'97 Modem Controller (rev 02)
???? 01:00.0 VGA compatible controller: nVidia Corporation NV17 [GeForce4 420 Go](rev a3)
???? 02:00.0 FireWire (IEEE 1394): VIA Technologies, Inc. IEEE 1394 Host Controller(rev 46)
???? 02:01.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+(rev 10)
???? 02:04.0 CardBus bridge: O2 Micro, Inc. OZ6933 Cardbus Controller (rev 01)
???? 02:04.1 CardBus bridge: O2 Micro, Inc. OZ6933 Cardbus Controller (rev 01)
???? lspci沒(méi)有標(biāo)明域,但對(duì)于一臺(tái)PC而言,一般僅僅有一個(gè)域,即0號(hào)域。通過(guò)這個(gè)輸出我們能夠看到它是一個(gè)IDE interface。由上述的 輸出能夠看到,我的電腦上共同擁有3個(gè)PCI總線(0號(hào),1號(hào),2號(hào))。在單個(gè)系統(tǒng)上,插入多個(gè)總線是通過(guò)橋(bridge)來(lái)完畢的,橋是一種用來(lái)連接總線 的特殊PCI外設(shè)。所以,PCI系統(tǒng)的總體布局組織為樹(shù)型,我們能夠通過(guò)上面的lspci輸出,來(lái)畫出我的電腦上的PCI系統(tǒng)的樹(shù)型結(jié)構(gòu):
00:00.0(主橋)--00:01.0(PCI橋)-----01:00:0(nVidia顯卡)
?????????????????? |
?????????????????? |---00:1d(USB控制器)--00:1d:0(USB1號(hào)控制器)
?????????????????? |??????????????????? |
?????????????????? |??????????????????? |--00:1d:1(USB2號(hào)控制器)??????????????????? |
?????????????????? |-00:1e:0(PCI橋)--02:00.0(IEEE1394)
?????????????????? |??????????????? |
?????????????????? |??????????????? |-02:01.0(8139網(wǎng)卡)
?????????????????? |??????????????? |
?????????????????? |??????????????? |-02:04(CardBus橋)-02:04.0(橋1)
?????????????????? |?????????????????????????????????? |
?????????????????? |?????????????????????????????????? |--02:04.1(橋2)
?????????????????? |
?????????????????? |-00:1f(多功能板卡)-00:1f:0(ISA橋)
??????????????????????????????????????? |
??????????????????????????????????????? |--00:1f:1(IDE接口)
??????????????????????????????????????? |
??????????????????????????????????????? |--00:1f:3(SMBus)
??????????????????????????????????????? |
??????????????????????????????????????? |--00:1f:5(多媒體聲音控制器)
??????????????????????????????????????? |
??????????????????????????????????????? |--00:1f:6(調(diào)制解調(diào)器)
???? 由上圖能夠得出,我的電腦上共同擁有8個(gè)PCI設(shè)備,當(dāng)中0號(hào)總線上(主橋)上連有4個(gè),1號(hào)總線上連有1個(gè),2號(hào)總線上連有3個(gè)。00:1f是一個(gè)連有5個(gè)功能的多功能板卡。
???? 每一個(gè)PCI設(shè)備都有它映射的內(nèi)存地址空間和它的I/O區(qū)域,這點(diǎn)是比較easy理解的。除此之外,PCI設(shè)備還有它的配置寄存器。有了配置寄存器, PCI的驅(qū)動(dòng)程序就不須要探測(cè)就能訪問(wèn)設(shè)備。配置寄存器的布局是標(biāo)準(zhǔn)化的,配置空間的4個(gè)字節(jié)含有一個(gè)獨(dú)一無(wú)二的功能ID,因此,驅(qū)動(dòng)程序可通過(guò)查詢外設(shè) 的特定 ID來(lái)識(shí)別其設(shè)備。所以,PCI接口標(biāo)準(zhǔn)在ISA之上的主要?jiǎng)?chuàng)新在于配置地址空間。
前文已講過(guò),PCI驅(qū)動(dòng)程序不須要探測(cè)就能訪問(wèn)設(shè)備,而這得益于配置地址空間。在系統(tǒng)引導(dǎo)階段,PCI硬件設(shè)備保持未激活狀態(tài),但每一個(gè)PCI主板均配備有能夠處理PCI的固件,固件通過(guò)讀寫PCI控制器中的寄存器,提供了對(duì)設(shè)備配置地址空間的訪問(wèn)。
???? 配置地址空間的前64字節(jié)是標(biāo)準(zhǔn)化的,它提供了廠商號(hào),設(shè)備號(hào),版本等信息,唯一標(biāo)識(shí)一個(gè)PCI設(shè)備。同一時(shí)候,它也提供了最多可多達(dá)6個(gè)的I/O 地址區(qū)域,每一個(gè)區(qū)域能夠是內(nèi)存也能夠是I/O地址。這幾個(gè)I/O地址區(qū)域是驅(qū)動(dòng)程序找到設(shè)備映射到內(nèi)存和I/O空間的具體位置的唯一途徑。有了這兩點(diǎn), PCI驅(qū)動(dòng)程序就完畢了相當(dāng)于探測(cè)的功能。關(guān)于這64個(gè)字節(jié)的配置空間的具體情況,可參閱《Linux設(shè)備驅(qū)動(dòng)程序第三版》P306,不再詳述。
???? 以下,我們來(lái)看一下8139too網(wǎng)卡設(shè)備的配置空間的具體情況。在2.6內(nèi)核的系統(tǒng)中,能夠在文件夾/sys/bus/pci/drivers/ 下看到非常多以PCI設(shè)備名命名的文件夾,但不是說(shuō)這些設(shè)備都存在于你的系統(tǒng)中。我們進(jìn)入8139too文件夾,當(dāng)中有一個(gè)以它的設(shè)備地址0000:02: 01.0命名的文件夾。在這個(gè)文件夾下能夠找到該網(wǎng)卡設(shè)備相關(guān)的非常多信息。當(dāng)中resource記錄了它的6個(gè)I/O地址區(qū)域。內(nèi)容例如以下:
???????? 0x0000000000003400 0x00000000000034ff 0x0000000000000101
???????? 0x00000000e0000800 0x00000000e00008ff 0x0000000000000200
???????? 0x0000000000000000 0x0000000000000000 0x0000000000000000
???????? 0x0000000000000000 0x0000000000000000 0x0000000000000000
???????? 0x0000000000000000 0x0000000000000000 0x0000000000000000
???????? 0x0000000000000000 0x0000000000000000 0x0000000000000000
???????? 0x0000000000000000 0x0000000000000000 0x0000000000000000
???? 由該文件能夠看出,8139too設(shè)備使用了兩個(gè)I/O地址區(qū)域,第一個(gè)是它映射的I/O端口范圍,第二個(gè)是它映射的內(nèi)存地址空間。關(guān)于這兩個(gè)值能夠在/proc/iomem和/proc/ioport中得到驗(yàn)證。
-[0000:00]-+-00.0
?????????? +-02.0
?????????? +-1d.0
?????????? +-1d.1
?????????? +-1d.2
?????????? +-1d.7
?????????? +-1e.0-[0000:01]--+-02.0
?????????? |???????????????? /-05.0
?????????? +-1f.0
?????????? +-1f.1
?????????? +-1f.3
?????????? /-1f.5
00:00.0 Host bridge: Intel Corporation 82845G/GL[Brookdale-G]/GE/PE DRAM Controller/Host-Hub Interface (rev 03)
00:02.0 VGA compatible controller: Intel Corporation 82845G/GL[Brookdale-G]/GE Chipset Integrated Graphics Device (rev 03)
00:1d.0 USB Controller: Intel Corporation 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 (rev 02)
00:1d.1 USB Controller: Intel Corporation 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 (rev 02)
00:1d.2 USB Controller: Intel Corporation 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 (rev 02)
00:1d.7 USB Controller: Intel Corporation 82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (rev 02)
00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev 82)
00:1f.0 ISA bridge: Intel Corporation 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge (rev 02)
(LPC Hub 控制器 1 )
00:1f.1 IDE interface: Intel Corporation 82801DB (ICH4) IDE Controller (rev 02)
00:1f.3 SMBus: Intel Corporation 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller (rev 02)
00:1f.5 Multimedia audio controller: Intel Corporation 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller (rev 02)
01:02.0 Communication controller: Conexant HSF 56k HSFi Modem (rev 01)
01:05.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+ (rev 10)