一、PCI簡單介紹 PCI是一種外設匯流排規範。我們先來看一下什麼是匯流排:匯流排是一種傳輸訊號的路徑或通道。典型情況是,匯流排是串連於一個或多個導體的電氣連線,總 線上串連的全部裝置可在同一時間收到全部的傳輸內容。匯流排由電氣介面和編程介面組成。本文討論Linux 下的裝置驅動,所以,重點關注編程介面。 PCI是Peripheral Component Interconnect(外圍裝置互聯)的簡稱,是普遍使用在案頭及更大型的電腦上的外 設匯流排。PCI架構被設計為ISA標準的替代品,它有三個主要目標:獲得在電腦和外設之間資料轉送時更好的效能;儘可能的平台無關;簡化往系統中加入和 刪除外設的工作。
二、PCI定址 從如今開始,我想儘可能通過一些實際的範例來說明問題,而降低理論方面的問題的描寫敘述,由於,相關的理論的東西,能夠在其他地方找到。 我們先來看一個範例,我的電腦裝有1G的RAM,1G以後的實體記憶體地址空間都是外部裝置IO在系統記憶體位址空間上的映射。 /proc/iomem描寫敘述了系統中全部的裝置I/O在記憶體位址空間上的映射。我們來看地址從1G開始的第一個裝置在/proc/iomem中是怎樣描寫敘述 的: 40000000-400003ff : 0000:00:1f.1 這是一個PCI裝置,40000000-400003ff是它所映射的記憶體位址空間,佔領了記憶體位址空間的1024 bytes的位置,而 0000:00:1f.1則是一個PCI外設的地址,它以冒號和逗號分隔為4個部分,第一個16位表示域,第二個8位表示一個匯流排編號,第三個5位表示一 個裝置號,最後是3位,表示功能號。 由於PCI規範同意單個系統擁有高達256個匯流排,所以匯流排編號是8位。但對於大型系統而言,這是不夠的,所以,引入了域的概念,每一個 PCI域能夠擁有最多256個匯流排,每一個匯流排上可支援32個裝置,所以裝置號是5位,而每一個裝置上最多可有8種功能,所以功能號是3位。由此,我們能夠得 出上述的PCI裝置的地址是0號域0號匯流排上的31號裝置上的1號功能。 那上述的這個PCI裝置究竟是什麼呢?以下是我的電腦上的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沒有標明域,但對於一台PC而言,一般僅僅有一個域,即0號域。通過這個輸出我們能夠看到它是一個IDE interface。由上述的 輸出能夠看到,我的電腦上共同擁有3個PCI匯流排(0號,1號,2號)。在單個系統上,插入多個匯流排是通過橋(bridge)來完畢的,橋是一種用來串連匯流排 的特殊PCI外設。所以,PCI系統的總體布局組織為樹型,我們能夠通過上面的lspci輸出,來畫出我的電腦上的PCI系統的樹型結構: 00:00.0(主橋)--00:01.0(PCI橋)-----01:00:0(nVidia顯卡) | |---00:1d(USB控制器)--00:1d:0(USB1號控制器) | | | |--00:1d:1(USB2號控制器) | |-00:1e:0(PCI橋)--02:00.0(IEEE1394) | | | |-02:01.0(8139網卡) | | | |-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(數據機) 由能夠得出,我的電腦上共同擁有8個PCI裝置,當中0號匯流排上(主橋)上連有4個,1號匯流排上連有1個,2號匯流排上連有3個。00:1f是一個連有5個功能的多功能板卡。 每一個PCI裝置都有它映射的記憶體位址空間和它的I/O地區,這點是比較easy理解的。除此之外,PCI裝置還有它的配置寄存器。有了配置寄存器, PCI的驅動程式就不須要探測就能訪問裝置。配置寄存器的布局是標準化的,配置空間的4個位元組含有一個獨一無二的功能ID,因此,驅動程式可通過查詢外設 的特定 ID來識別其裝置。所以,PCI介面標準在ISA之上的主要創新在於配置地址空間。 前文已講過,PCI驅動程式不須要探測就能訪問裝置,而這得益於配置地址空間。在系統引導階段,PCI硬體裝置保持未啟用狀態,但每一個PCI主板均配備有能夠處理PCI的韌體,韌體通過讀寫PCI控制器中的寄存器,提供了對裝置配置地址空間的訪問。 配置地址空間的前64位元組是標準化的,它提供了廠商號,裝置號,版本等資訊,唯一標識一個PCI裝置。同一時候,它也提供了最多可多達6個的I/O 地址地區,每一個地區能夠是記憶體也能夠是I/O地址。這幾個I/O地址地區是驅動程式找到裝置映射到記憶體和I/O空間的具體位置的唯一途徑。有了這兩點, PCI驅動程式就完畢了相當於探測的功能。關於這64個位元組的配置空間的具體情況,可參閱《Linux裝置驅動程式第三版》P306,不再詳述。 以下,我們來看一下8139too網卡裝置的配置空間的具體情況。在2.6核心的系統中,能夠在檔案夾/sys/bus/pci/drivers/ 下看到非常多以PCI裝置名稱命名的檔案夾,但不是說這些裝置都存在於你的系統中。我們進入8139too檔案夾,當中有一個以它的裝置地址0000:02: 01.0命名的檔案夾。在這個檔案夾下能夠找到該網卡裝置相關的非常多資訊。當中resource記錄了它的6個I/O地址地區。內容例如以下: 0x0000000000003400 0x00000000000034ff 0x0000000000000101 0x00000000e0000800 0x00000000e00008ff 0x0000000000000200 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 由該檔案能夠看出,8139too裝置使用了兩個I/O地址地區,第一個是它映射的I/O連接埠範圍,第二個是它映射的記憶體位址空間。關於這兩個值能夠在/proc/iomem和/proc/ioport中得到驗證。 -[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) |