Linux子系統系列-PCI

來源:互聯網
上載者:User

趁這幾天有空,將PCI這塊的東西也簡單整理一下。關於PCI,fudan_abc大俠的“PCI那些事兒”是最佳的,這裡簡單根據一些工作筆記做些整理,點一下大致架構,以作備忘。

0,背景

1,PCI driver結構

2,PCI driver實現

3,關於PCI core

------------------------------------------------------------------------------

0,背景

PCI,十多年前就有的一個匯流排標準,曆久彌新,生命力旺盛。雖然現在基於PCI有了很多派生,但符合PCI標準的裝置還是隨處可見。其原因琢磨著可能有兩個:PCI匯流排標準極大的降低了硬體裝置驅動的編寫難度和繁瑣度;Linux驅動模型對PCI裝置驅動的抽象更進一步降低了PCI驅動的難度。設計時除了單獨的商業目的多考慮一下終端使用者或開發人員,市場一定會給你豐厚的回報,:)

在分析或編寫PCI driver之前一定要瞭解一下PCI系統在電腦中的全貌,下面大部引自fudan_abc的文章:

PCI的結構中會涉及到bridge的概念,所謂橋,是用來將多個PCI匯流排,或PCI匯流排於ISA等其他匯流排串連起來的東西。各種橋裡面比較特殊的一個是Host bridge,它串連的是CPU和PCI匯流排0,它整合在我們常說的北橋中(北橋和南橋並稱晶片集,晶片集裡距離CPU最近的就是北橋)。明白了Host Bridge,再來看看PCI bus0,也就是primary PCI bus,主PCI匯流排,可能還會有PCI bus1,PCI bus2,但PCI bus0是一定存在的。一個系統可以擁有多個PCI匯流排,這多個PCI匯流排之間的串連要靠另外一種橋,PCI-PCI橋。通過了PCI-PCI橋,整個PCI系統就構成了一個層次的、樹狀地結構,這些樹就像HUB同是USB裝置一樣,PCI-PCI橋等各種各樣的橋也都是PCI裝置。每個PCI匯流排上可以支援32個PCI裝置,每個裝置又可以支援8種功能,這裡所謂的裝置一般指那種PCI匯流排上的具體卡/裝置/晶片,每塊PCI卡上可以有若干個功能模組,它們共用了同一個PCI卡,從邏輯的角度來說,每個功能模組都是一個邏輯裝置。

明白了PCI系統的結構,匯流排枚舉的概念又來了:

按照規範,每個PCI裝置都有那麼一張表,就是所謂的配置寄存器,相應的驅動編寫都要依賴這種表。這個表中的一部分內容都固化在了PCI裝置的晶片裡面,擷取的就要去訪問PCI裝置。但系統一開始只有那條PCI bus0能夠訪問,其他的PCI匯流排和裝置一切都還是未知, 要把這些未知變為已知,這就需要匯流排枚舉。系統引導時,對於PCI子系統來說,會首先有個匯流排枚舉的階段,從PCI bus0開始掃描,遇到一個裝置是PCI-PCI橋,就指定一個新的匯流排號,比如1,這樣PCI bus1就有了,也就可以繼續掃描了,如果遇到一個其他PCI裝置,就將它記錄下來,直到將所有的PCI-PCI橋和PCI裝置給晾出來,組成系統的PCI樹。

1,PCI driver結構

PCI裝置的驅動一般分為兩層,最下一層是linux的PCI core子系統,上層是根據具體晶片實現的一些操作。

2,PCI driver的實現

一個完整的PCI driver要完成以下工作:

1)定義一個這個驅動可以支援的裝置的表

static const struct pci_device_id cmd64x_pci_tbl[] = {
    { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 },
    { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 },
    { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_648), 2 },
    { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_649), 3 },
    { 0, },
};

2)在編譯時間,driver將會使用MODULE_DEVICE_TABLE宏將這個list傳遞給build system(不是kernel)

我們在make module_install時,這個表的內容會被轉譯成module的一個資料庫的內容,被安裝在使用者側。

當系統發現一個新的PCI裝置時,PCI core 會向kernel發出一個通知,kernel接著會將這個通知轉向使用者層這類通知的監聽程式(udev)通過uevents機制。udev會從uevent中解析出這個通知的裝置資訊並調用modprobe。緊接著,modprobe會基於這些資訊分析modules.alias,安裝相應的模組。

3)使用PCI core的API:pci_register_device()註冊裝置資訊。

4)PCI core會根據註冊的裝置資訊來掃描是否有匹配的驅動,若發現,PCI core會調用probe函數來讓driver擷取PCI裝置的控制權。

 

3,關於PCI core

linux的工程師們將PCI相關的一些與平台/晶片無關的一些操作抽象出來,形成這個PCI core子系統。這個子系統除了提供一些PCI相關的API之外,還可以方便快捷的將driver以符合linux裝置模型規範的方式註冊到kernel。

無需多說,用過的都說好:

1)保持盡量一致的對外介面,增加你的驅動的可移植性。

2)通過/sysfs提供一些常用介面到使用者側,方便管理調試。

3)讓udev可以自動為PCI裝置建立/dev目錄下的節點並load需要的module。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.