1. 程式人生 > >Linux裝置與驅動學習筆記(概述)

Linux裝置與驅動學習筆記(概述)

由於在下能力相當有限,有不當之處,還望批評指正^_^

一、概述

在核心中,匯流排/裝置/驅動模型實現了對匯流排/裝置/驅動的管理。

涉及的概念有struct bus_type(匯流排型別)。

核心並不關心每種匯流排的實現細節,也未預先定義一共有哪些具體的匯流排型別。

因此,開發者甚至可以自己定義一種匯流排型別,註冊到核心中。

如下是PCI匯流排型別的定義。相當於是將PCI匯流排共性的部分進行了包裝。

struct bus_type pci_bus_type = {
.name= "pci",
.match= pci_bus_match,
.uevent= pci_uevent,
.probe= pci_device_probe,
.remove= pci_device_remove,
.shutdown= pci_device_shutdown,
.dev_attrs= pci_dev_attrs,
.bus_attrs= pci_bus_attrs,
.drv_attrs= pci_drv_attrs,
.pm= PCI_PM_OPS_PTR,

};

struct pci_bus則代表了一條具體的PCI匯流排,他包含了匯流排號,還用連結串列將其下面掛著的裝置全部串了起來。

然後,struct pci_driver和struct pci_dev分別表示pci驅動與pci裝置。

除了pci匯流排,核心中還有i2c、spi、usb、platform等匯流排,涉及到的概念大體類似。

需要特別注意的是,對於匯流排裝置驅動模型,核心關鍵詞是管理。

每一個匯流排型別,體現了外設接入系統的一種方式。

有些裝置,並沒有通過某種匯流排接入系統,而是直接掛在了系統總線上。為了架構的統一,對於這種裝置,核心抽象出了一種特殊的匯流排—platform匯流排,然後將這些裝置都歸到platform匯流排中。

這樣,核心就將匯流排型別、匯流排、裝置驅動、裝置很有條理的管理了起來,同時還對裝置與驅動進行匹配。

需要注意的是,核心的這種管理結構,只關心管理層面的資訊,並不關心所管理物件的別的方面的資訊。

例如,某匯流排具體是如何與外設連線的,原理是什麼,各種操作是怎麼實現的,某裝置是幹什麼的,某驅動要如何設定暫存器,如何處理中斷,如何將所驅動裝置的功能提供給使用者使用。

這些內容,管理層面都是不關心的。

而對於各種各樣的驅動而言,所要做的操作主要包含如下三種。

與裝置互動(對於pci裝置可直接讀寫暫存器,對於i2c裝置可通過匯流排控制器與之互動)

處理中斷

向核心註冊一個物件(如cdev/net_device/input_dev等等),使得系統可以將這個裝置用起來

另外,驅動可能還會針對接管的每個裝置,在/sys下面建立一些屬性檔案,以便使用者可以通過這些屬生與裝置進行互動。

一般來說,驅動會針對接管的每一個裝置,建立一個結構變數,用於維護上述各種操作可能涉及的各種上下文資訊。

好了,下面還是看看匯流排裝置驅動模型相關內容吧。

sys檔案系統與匯流排裝置驅動模型

/sys/bus/目錄下列出了各種匯流排型別,像pci、i2c、usb、platform等。

我們以pci匯流排為例,看看相關概念。

/sys/bus/pci/devices/目錄下則則列出了所有系統中存在的所有pci裝置(不管有沒有安裝對應的驅動程式)的名稱,pci裝置的名稱即pci地址(即 "域:pci匯流排號:槽位號:功能號")。下面的示例輸出,限於篇幅,只列出了幾個裝置作為樣例。

[[email protected] char]# ls /sys/bus/pci/devices/
0000:00:00.0  0000:03:00.0  0000:06:12.7  0000:06:16.3

/sys/bus/pci/drivers目錄下則列出了所有已載入的所有pci裝置的驅動。

下面的示例輸出,列出了pci裝置驅動ixgbe(一款網絡卡驅動程式),以及當前接管了哪些裝置(0000:06:00.0和0000:06:00.1)。

[[email protected] char]# ls /sys/bus/pci/drivers/ixgbe  
0000:06:00.0  0000:06:00.1  bind  module  new_id  remove_id  uevent  unbind

示例輸出中還有一些別的檔案,像bind用來指定某個pci裝置由此驅動接管,unbind則起相反的作用。通常,一個驅動都有自己支援的裝置型號的列表。new_id用於動態增加此驅動可以接管的裝置型號,remove_id則起相反作用。

【注】

pci裝置的名稱,是通過如下方式設定的

dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
     dev->bus->number, PCI_SLOT(dev->devfn),
     PCI_FUNC(dev->devfn));

而其他型別的裝置,命名方式也名異。下面列出了其他幾種裝置的命名方式

(i) isa

dev_set_name(&isa_dev->dev, "%s.%u",
    isa_driver->driver.name, id);

(ii)platform

if (pdev->id != -1)
dev_set_name(&pdev->dev, "%s.%d", pdev->name,  pdev->id);
else
dev_set_name(&pdev->dev, "%s", pdev->name);

(iii)I2C

dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
    client->addr);

【注】

有時候,可能會存在多個驅動,都可以驅動某一個裝置的情況。

這時候,使用者可以執行將裝置與驅動進行繫結或解除繫結的操作。

將裝置與驅動繫結的方法為:

echo  dev_name  > /sys/bus/bus_type/drivers/driver_name/bind

將裝置與驅動解除繫結的方法為:

echo  dev_name  > /sys/bus/bus_type/drivers/driver_name/unbind

例如,將名稱為0000:06:00.1的pci裝置與名為ixgbe的驅動繫結,則命令如下:

echo 0000:06:00.1 > /sys/bus/pci/drivers/ixgbe/bind

echo命令執行後,由driver_bind/driver_unbind函式執行具體的繫結與解綁。

這兩個函式對應於sys檔案系統的store操作。

當然,除了pci匯流排,還有別的匯流排型別。

不同型別的匯流排,有著不同的原理與概念。

下面列出了若干不同型別匯流排的裝置,可以看到其命名風格的不同。

[[email protected] char]# ls /sys/bus/i2c/devices/
2-007c  i2c-0  i2c-1  i2c-2  i2c-3

[[email protected] char]# ls /sys/bus/usb/devices/
1-0:1.0  1-1  1-1:1.0  1-1.3  1-1.3:1.0  1-1.3:1.1  2-0:1.0  2-1  2-1:1.0  usb1  usb2

[[email protected] char]# ls /sys/bus/platform/devices/
alarmtimer  coretemp.1        GHES.0  gpio_ich         iTCO_wdt   pcspkr
coretemp.0  Fixed MDIO bus.0  GHES.1  ipmi_bmc.3060.8  microcode  serial8250

相關核心原始碼

裝置驅動方面的核心程式碼,位於drivers/base目錄下。core.c是裝置管理的核心檔案,driver.c是驅動管理的核心檔案,bus.c是匯流排處理的核心檔案。我們可以以他們為線索,看出不同模組之間的呼叫關係,同時也能看出核心在管理裝置與驅動方面的精妙設計理念。

在看程式碼之前,先來聊聊裝置、驅動、匯流排之間的關係,同時引出一些核心中的重要資料結構。首先說說裝置。不管是什麼奇奇怪怪的裝置,它畢竟都是一個裝置。所以,在這個層次上,可以將一切裝置都歸納到裝置這個集合中去管理。就像動物一樣,不管是人,還是豬馬牛羊,站在動物這個層次上,都可以歸屬到動物這個類別中去。

在核心中,用於表示一個裝置的資料結構是 struct device。

再來說說驅動。同理,一切驅動都是驅動,自然也是統一管理。

核心中,表示一個驅動的資料結構是 struct device_driver。

好了,現在已經有了裝置與驅動的表示方法。但是,這是站在最高層次上做出的概念抽象。

不同型別匯流排的裝置,其標識方法也各有不同。

實際上,核心原始碼中也為此定義了不同型別的結構來標識之。

例如,struct platform_device_id用於標識platform裝置,struct pci_device_id用於標識pci裝置。


未完...


相關推薦

Linux裝置驅動學習筆記(概述)

由於在下能力相當有限,有不當之處,還望批評指正^_^一、概述在核心中,匯流排/裝置/驅動模型實現了對匯流排/裝置/驅動的管理。涉及的概念有struct bus_type(匯流排型別)。核心並不關心每種匯流排的實現細節,也未預先定義一共有哪些具體的匯流排型別。因此,開發者甚至可

採用大資料的商業動機驅動 ------ 學習筆記

概念: 架構:架構是針對某種特定目標系統的具有體系性的、普遍性的問題而提供的通用的解決方案 業務架構是基於業務導向和驅動的架構來理解、分析、設計、構建、整合、擴充套件、執行和管理資訊系統,比如業務架構體系認為一個資訊系統必須由組織機構、業務流程、業務資訊、業務功能、和業務語義等層次構成。為實

Linux系統SPI驅動學習筆記(一)

  SPI是"Serial Peripheral Interface" 的縮寫,是一種四線制的同步序列通訊介面,用來連線微控制器、感測器、儲存裝置,SPI裝置分為主裝置和從裝置兩種,用於通訊和控制的四根線分別是: CS    片選訊號SCK  時鐘訊號MISO  主裝置的

linux I2C 裝置驅動學習筆記

一:I2C 概述           I2C是philips提出的外設匯流排.使用SCL時鐘線,SDA序列資料線這兩根訊號線就實現了裝置之間的資料互動,被非常廣泛地應用在CPU與EEPROM,實時鐘,小型LCD等裝置通訊中。  二:在linux下的驅動思路     linu

linux裝置驅動學習筆記--核心除錯方法之printk

1,printk類似於使用者態的printf函式,但是比printf函式多了一個日誌級別,核心中最常見的日誌輸出都是通過呼叫printk來實現的,其列印級別有8種可能的記錄字串, 在標頭檔案 <linux/kernel.h> 裡定義: KERN_EMERG

linux裝置驅動學習筆記--核心除錯方法之proc(補充seq_file)

上一節中的proc實現對於開關檔案,控制檔案,以及顯示很少資訊的檔案來說還是比較簡單的,但是對於需要輸出大量資訊像meminfo,或者結構化的資訊像cpuinfo等時就會顯得很笨拙,並且程式碼也很不好理解與維護。核心為了簡化這種proc檔案的實現提供了另外一種方案----s

Linux驅動學習筆記----------IIC框架流程(一)

歷時一個月期末課程設計終於結束了!發現好多東西忘記了,iic流程也有些淡忘,有點慌,夜深人靜的時候就整理下吧!還有,杭州最近熱的我腦袋都不好用了! 關於iic: 1.是一種資料傳輸協議(spi,usb,sdio,uart…)

linux裝置驅動學習筆記--核心除錯方法之proc

/proc 檔案系統是 GNU/Linux 特有的。它是一個虛擬的檔案系統,因此在該目錄中的所有檔案都不會消耗磁碟空間。通過它能夠非常簡便地瞭解系統資訊,尤其是其中的大部分檔案是人類可閱讀的(不過還是需要一些幫助)。許多程式實際上只是從 /proc 的檔案中收集資訊,然後按

《鳥哥的linux私房菜》學習筆記2-檔案目錄管理查閱(思維導圖)

1、常見處理目錄的命令:cd,pwd,mkdir,rmdir 2、檔案與目錄的管理:ls(https://blog.csdn.net/weixin_42610712/article/details/83032052),cp,rm,mv,touch 3、檔案內容查閱——cat 4、檔案內容

linux驅動學習筆記---s5pv210(一)

1,解壓核心原始碼 tar -xvf linux-3.0.8.tar.bz2 2,核心的編譯步驟:     a,設定交叉工具鏈--目標檔案執行在arm處理上, 修改Makefile          195 ARCH            ?= arm          1

Arm+Linux核心驅動學習筆記

韋東山老師幫我們把框架搭建起來了,我們先來看一下: 框架: app:      open,read,write "1.txt" ---------------------------------------------  檔案的讀寫 檔案系統: vfat, ext2,

Linux裝置驅動--LCD平臺裝置驅動(tiny4412)

1 環境與簡介     Host:Ubuntu14.04(64bit)     Target:Tiny4412     Kernel:linux-3.5.0 2 平臺裝置 2.1 宣告 extern struct platform_device s5p_device_fim

Python 下字串的連線、簡單替換unicode字串- 千月的python linux 系統管理指南學習筆記(12)

Python 下字串的連線、簡單替換與unicode字串 繼續上一章的內容,看一看字串的連線和替換 字串的連線 join() 將多個字串連線起來的”膠水“ 字元物件.join(字串或者列表) #連線字串,或者與列表裡的字元分別連線。 光是將2個字串相連。其實意義不大,一個

Linux裝置驅動match過程

在之前的學習過程中,我們知道了Linux 裝置驅動匯流排架構,抽象硬體上裝置都是掛載在匯流排BUS上的,所以,定義了各種匯流排結構體。這裡用platform_bus_type為例struct bus_type platform_bus_type = { .name= "pla

Python 下字串的提取、分割刪除- 千月的python linux 系統管理指南學習筆記(11)

Python 下字串的提取、分割與刪除 對於文字來講,提取、分割和刪除是我們用的較多的操作。 文字我們可以看成是字串物件。首先說到的是 in 和 not in操作。 字串的提取 in 和 not i

Linux裝置驅動--LCD平臺裝置驅動(smdk2440)

1 環境與簡介     Host:Ubuntu14.04(64bit)     Target:smdk2440     Kernel:linux-2.6.39.4     類似於《Linux裝置驅動--WDT平臺裝置與驅動》,本文再以LCD為例進行說明。本文的原始碼均來自L

Linux匯流排、裝置驅動》自己寫的demo

本demo基於Android2.3模擬器開發,核心程式碼(Linux2.6.29)和Android程式碼可以在網上下載、這裡不在說明。 一、驅動 1.匯流排驅動 功能:匯流排驅動;提供設備註冊和裝置驅動註冊以及裝置與裝置驅動匹配等函式功能。 testbus.c #inc

Linux裝置驅動--LCD平臺裝置驅動(s3c64xx)

1 開發環境     Host:Ubuntu14.04     Target:s3c64xx     Kernel:linux-3.18.2 2 平臺裝置         關於裝置樹是如果被載入並解析成裝置節點的,詳見參考資料[1],本文重點分析如何利用裝置節點建立相

Linux指令碼攻略學習筆記之臨時檔案命名隨機數

最適合儲存臨時資料的位置是 /tmp(該目錄中的內容在系統重啟後會被清空) mktemp 命令的用法非常簡單。它生成一個臨時檔案並返回其檔名(如果建立的是目錄,則返回目錄名)。如果提供了定製模板, X

Linux裝置驅動--LCD平臺裝置驅動(smdk6410)

1 環境與簡介     Host:Ubuntu14.04(64bit)     Target:smdk6410     Kernel:linux-3.5.0     在《Linux裝置驅動--LCD平臺裝置與驅動(smdk2440)》中基於linux-2.6.39.4對LC