Linux裝置驅動模型框架分析(三)——LDDM的實體bus_type、device和device_driver
在Linux裝置模型中,Bus(匯流排)是一類特殊的裝置,它是連線處理器和其它裝置之間的通道(channel)。為了方便裝置模型的實現,核心規定,系統中的每個裝置都要連線在一個Bus上,這個Bus可以是一個內部Bus、虛擬Bus或者Platform Bus。
device和device driver是Linux驅動開發的基本概念。Linux kernel的思路很簡單:驅動開發,就是要開發指定的軟體(driver)以驅動指定的裝置,所以kernel就為裝置和驅動它的driver定義了兩個資料結構,分別是device和device_driver(本文以http://www.wowotech.net/device_model/device_and_driver.html,http://www.wowotech.net/device_model/bus.html為基礎,結合自己的理解和4.1核心的修改)。
bus_type
核心通過struct bus_type結構,抽象Bus。
name,該bus的名稱,會在sysfs中以目錄的形式存在,如platform bus在sysfs中表現為"/sys/bus/platform”。
dev_name,該名稱和下面講到的struct device結構中的init_name有關。對有些裝置而言,允許將裝置的名字留空。這樣當設備註冊到核心後,裝置模型的核心邏輯就會用"bus->dev_name+device ID”的形式,為這樣的裝置生成一個名稱。
dev_attrs,被下邊的groups取代
bus_groups、dev_groups、drv_groups
dev_root,dev_root裝置為bus的預設父裝置(Default device to use as the parent),但在核心實際實現中,和一個叫sub system的功能有關。
match,一個由具體的bus driver實現的回撥函式。當任何屬於該Bus的device或者device_driver新增到核心時,核心都會呼叫該介面,如果新加的device或device_driver匹配上了彼此的話,該介面要返回非零值,此時Bus模組的核心邏輯就會執行後續的處理。
uevent,一個由具體的bus driver實現的回撥函式。當任何屬於該Bus的device,發生新增、移除或者其它動作時,Bus模組的核心邏輯就會呼叫該介面,以便bus driver能夠修改環境變數。
probe、remove,這兩個回撥函式,和device_driver中的非常類似,但它們的存在是非常有意義的。可以想象一下,如果需要probe(其實就是初始化)指定的device話,需要保證該device所在的bus是被初始化過、確保能正確工作的。這就要就在執行device_driver的probe前,先執行它的bus的probe。remove的過程相反。
並不是所有的bus都需要probe和remove介面的,因為對有些bus來說(例如platform bus),它本身就是一個虛擬的匯流排,無所謂初始化,直接就能使用,因此這些bus的driver就可以將這兩個回撥函式留空。
shutdown、suspend、resume,和probe、remove的原理類似,電源管理相關的實現。
online、offline,和屬於這個匯流排裝置的online屬性相關。
pm,電源管理相關的邏輯。
iommu_ops,匯流排的IOMMU相關操作,IOMMU與MMU功能類似,可以給裝置一個核心空間的地址(或叫匯流排地址),而不限於可以直接訪問的常規記憶體區域。
p,一個struct subsys_private型別的指標,kobject隱藏在這個結構後面。這個結構也很重要。
device
device結構很複雜,這裡將會選一些對理解裝置模型非常關鍵的欄位進行說明。
parent,該裝置的父裝置,一般是該裝置所從屬的bus、controller等裝置。
p,一個用於裝置的私有資料結構指標,儲存子裝置連結串列,新增父節點,鄰居節點和匯流排連結串列等。
kobj,該資料結構對應的struct kobject。
init_name,該裝置的名稱。
在裝置模型中,名稱是一個非常重要的變數,任何註冊到核心中的裝置,都必須有一個合法的名稱,可以在初始化時給出,也可以由核心根據“bus name + device ID”的方式創造。見bus_type.dev_name的說明。
type,struct device_type結構是新版本核心新引入的一個結構,它和struct device關係,非常類似stuct kobj_type和struct kobject之間的關係。
bus,該device屬於哪個匯流排。
driver,該device對應的device driver。
platform_data,一個指標,用於儲存具體的平臺相關的資料。linux經常用來儲存一些單板相關的資料,來描述包含哪些裝置,以及它們如何互聯。以便大幅減少BSP的程式碼量和驅動中ifdef的使用。
power、pm_domain,電源管理相關的邏輯,後續會由電源管理專題講解。
pins,"PINCTRL”功能。
numa_node,"NUMA”功能。
devt,裝置號。在這裡,該變數主要用於在sys檔案系統中,為每個具有裝置號的device,建立/sys/dev/*下的對應目錄,如下:
class,該裝置屬於哪個class。這從側面說明了class是device的集合。
groups,該裝置的預設attribute集合。將會在設備註冊時自動在sysfs中建立對應的檔案。
device_driver
name,該driver的名稱。和device結構一樣,該名稱非常重要,和device和driver的匹配有關。
bus,該driver所驅動裝置的匯流排裝置。核心要保證在driver執行前,裝置所依賴的匯流排能夠正確初始化。
owner、mod_name,核心module相關的變數。
suppress_bind_attrs,通過sysfs啟用bind和unbind的attribute,如下:
# ls /sys/bus/platform/drivers/switch-gpio/
bind uevent unbind
在kernel中,bind/unbind是從使用者空間手動的為driver繫結/解繫結指定的裝置的機制。
probe、remove,這兩個介面函式用於實現driver邏輯的開始和結束。在裝置模型的結構下,只有driver和device同時存在時,才需要開始執行driver的程式碼邏輯。這也是probe和remove兩個介面名稱的由來:檢測到了裝置和移除了裝置(就是為熱拔插起的!)。
shutdown、suspend、resume、pm,電源管理相關的內容。
groups,和struct device結構中的同名變數類似,driver也可以定義一些預設attribute,這樣在將driver註冊到核心中時,核心裝置模型部分的程式碼會自動將這些attribute新增到sysfs中。
p,私有資料的指標。
subsys_private
舊的linux存在獨立的子系統資料結構subsystem,2.6.35拋棄了這個資料結構。轉而用subsys_private表示。
什麼是子系統?無論是bus,還是class,還是一些虛擬的子系統,它都構成了一個“子系統(sub-system)”,該子系統會包含形形色色的device或device_driver,就像一個獨立的王國一樣,存在於核心中。而這些子系統的表現形式,就是/sys/bus(或/sys/class,或其它)目錄下面的子目錄,每一個子目錄,都是一個子系統(如/sys/bus/spi/)。從子系統的角度看bus和後面的class很類似,它們都用subsys_private表示子系統。
subsys、devices_kset、drivers_kset是三個kset。其中subsys,代表了本bus(如/sys/bus/spi),它下面可以包含其它的kset或者其它的kobject;devices_kset和drivers_kset則是bus下面的兩個kset(如/sys/bus/spi/devices和/sys/bus/spi/drivers),分別包括本bus下所有的device和device_driver。bus_type與kobject的關係通過subsys成員體現。通過巨集to_subsys_private(obj)可以看出。
interface,用於儲存該bus下所有的interface。interface抽象了此類子系統的專有功能。
klist_devices、klist_drivers,分別儲存了本bus下所有的device和device_driver的指標,以方便查詢。
drivers_autoprobe,用於控制該bus下的drivers或者device是否自動probe。
bus、class,分別儲存上層的bus或者class指標。
device_private
klist_childre,包含此裝置所有的子裝置。
knode_parent,連入父裝置的klist_children時所用的節點。
knode_driver,連入驅動的裝置連結串列所用的節點,driver_private的klist_devices節點。
knode_bus,連入匯流排的裝置連結串列時所用的節點,subsys_private中klist_devices的節點。
deferred_probe,deferred_probe_list的入口,deferred_probe_list用來重新繫結那些暫時不能獲得device全部資源的驅動,這種情況常常是因為某一個驅動需要另一個驅動首先probe。
device,指向包含device_private的device
driver_private
kboj,結構對應的kobject。
klist_devices,包含此驅動可以驅動的裝置。
knode_bus,連入bus的驅動連結串列的節點,代表subsys_private中klist_drivers的節點。
mkobj,核心module相關變數。
driver,指向包含driver_private的driver。
device_type
name,表示該型別的名稱,當該型別的裝置新增到核心時,核心會發出"DEVTYPE=‘name’”型別的uevent,告知使用者空間某個型別的裝置available了。
groups,該型別裝置的公共attribute集合。設備註冊時,會同時註冊這些attribute。這就是面向物件中“繼承”的概念。
uevent,所有相同型別的裝置,會有一些共有的uevent需要傳送,由該介面實現。
release,如果device結構沒有提供release介面,就要查詢它所屬的type是否提供,用於釋放device變數所佔的空間。
bus_type,device和device_driver與kobject的關係
從device和device_driver的角度看
device和device_driver直接繼承kobject,bus_type通過subsys_private與kobject發生聯絡。圖中kset和kobject的關係是從kset與包含在它裡邊的kobject的角度看的,與前面kset與kobjcet的關係角度不同。由此可見,匯流排、裝置和驅動是建立在kobject基礎上的,藉由kobject和kset建立層次關係。
bus_type,device、device_driver的關係
一個device_driver可以支援多個device。bus_type通過subsys_private與device_driver和device發生關聯。
bus_type、device、device_driver與sysfs的關係
匯流排,裝置和裝置驅動與sysfs的對應關係相對簡單直觀。
核心資料結構或成員 |
sysfs對應表現形式 |
bus_type.name |
/sys/bus下的目錄名 |
bus_type.dev_name |
裝置委託給匯流排給其一個名字,如果裝置沒有起名,與device_id一起作為/sys/devices下的目錄名 |
device.name |
/sys/devices下的目錄名 |
driver.name |
/sys/devices下的目錄名 |
相關推薦
Linux裝置驅動模型框架分析(三)——LDDM的實體bus_type、device和device_driver
在Linux裝置模型中,Bus(匯流排)是一類特殊的裝置,它是連線處理器和其它裝置之間的通道(channel)。為了方便裝置模型的實現,核心規定,系統中的每個裝置都要連線在一個Bus上,這個Bus可以是一個內部Bus、虛擬Bus或者Platform Bus。 device
Linux裝置驅動模型框架分析(五)——LDDM的展現:sysfs
sysfs是一個基於RAM的檔案系統,它和kobject一起,可以將Kernel的資料結構匯出到使用者空間,以檔案目錄結構的形式,提供對這些資料結構(以及資料結構的屬性)的訪問支援。 sysfs目錄 所包含內容 /sys/devices 這是核心對系統中所有
linux裝置驅動模型架構分析(一)——概述
概述 LDD3中說:“Linux核心需要一個對系統結構的一般性描述。”這個描述就是linux裝置驅動模型(下面簡稱為LDDM)。LDDM不是獨立存在,其體系如下圖所示: LDDM體系結構 對架構的每一部分本文都會開闢獨立的章節進行描述。暫且拋開這個架構,首先從總體上了
【原創】Linux PCI驅動框架分析(三)
# 背 景 - `Read the fucking source code!` --By 魯迅 - `A picture is worth a thousand words.` --By 高爾基 說明: 1. Kernel版本:4.14 2. ARM64處理器 3. 使用工具:Source Insight
linux裝置驅動模型架構分析 一
概述LDD3中說:“Linux核心需要一個對系統結構的一般性描述。”這個描述就是linux裝置驅動模型(下面簡稱為LDDM)。LDDM不是獨立存在,其體系如下圖所示:對架構的每一部分本文都會開闢獨立的章節進行描述。暫且拋開這個架構,首先從總體上了解一下LDDM。LDDM與驅動
《Linux驅動》iTop4412開發板LCD驅動 詳細分析 (三)
接下來我們來詳解介紹probe中的函式: 第一個函式: s3cfb_set_lcd_info(fbdev[i]); 1.該函式原始碼如下: /*該函式在s3cfb_wa101s.c 中*/ /* name should be fixed as
字元裝置驅動核心框架小結(一)
最近一直在學習驅動相關知識,但是如果說會用或者簡單的會寫的話我還不是很滿足,我還是想知道它底層是如何實現的。那閒話少說,最近也看了很多大牛的經驗總結,然後也就談談自己的看法吧~ 首先還是先列個大綱: 1、VFS如何實現; 2、字元裝置驅動框架; 一、VFS(
flume(三):常見source、channel和sink總結
一、核心關注點 因為flume版本不同,source、channel和sink的介面都是不一樣的,所以需要使用對應版本的介面。 本文以flume1.6.0為例,參考http://archive.cloudera.com/cdh5/cdh/5/flume-ng-1.6.0-c
MySQL優化系列(三)--索引的使用、原理和設計優化
之前的文章一直在規避索引的建立去優化資料庫,不是不想講,而是這個太重要,必須抽出來講。今天我們就來研究下資料庫索引的設計與優化(MySQL為例)。 文章結構:(1)索引的概述和使用;(2)索引的基本原理;(3)索引分類;(4)索引設計優化
javascript 面向物件學習(三)——this,bind、apply 和 call
this 是 js 裡繞不開的話題,也是非常容易混淆的概念,今天試著把它理一理。 this 在非嚴格模式下,總是指向一個物件,在嚴格模式下可以是任意值,本文僅考慮非嚴格模式。記住它總是指向一個物件對於理解它的意義很重要。this 在實際使用中,大致分為以下幾種情況: 1. 函式作為物件的方法呼叫時,this
linux裝置驅動模型 - 驅動框架
linux驅動模型框架如圖所示: 1. kernfs 驅動最終是提供給使用者層使用,那麼其中的介面就是通過kernfs檔案系統來註冊,kernfs是一個通用的核心虛擬檔案系統 2. sysfs/kobject sysfs是裝置驅動檔案系統,裝置之間的各種關係會在在/
Linux裝置驅動程式架構分析之I2C架構(基於3.10.1核心)
作者:劉昊昱 核心版本:3.10.1 I2C體系架構的硬體實體包括兩部分: 硬體I2C Adapter:硬體I2C Adapter表示一個硬體I2C介面卡,也就是I2C控制器。一般是SOC中的一個介面,也可以用GPIO模擬。硬體I2C Adapter主要用來在I2
Linux裝置驅動程式架構分析之MMC/SD(二)
作者:劉昊昱 核心版本:3.10.1 一、s3cmci_ops分析 在上一篇文章中我們分析了Mini2440 MMC/SD驅動的probe函式s3cmci_probe。在該函式中初始化了struct mmc_host指標變數mmc,其中,設定mmc->ops為s
Linux裝置驅動程式架構分析之platform(基於3.10.1核心)
作者:劉昊昱 核心版本:3.10.1 一、platform bus的註冊 platform bus註冊是通過platform_bus_init函式完成的,該函式定義在drivers/base/platform.c檔案中,其內容如下: 904int __init pl
Linux裝置驅動模型簡述(原始碼剖析)
1. Linux裝置驅動模型和sysfs檔案系統 Linux核心在2.6版本中引入裝置驅動模型,簡化了驅動程式的編寫。Linux裝置驅動模型包含裝置(device)、匯流排(bus)、類(class)和驅動(driver),它們之間相互關聯。其中裝置(device)和驅動(driver)通過匯流排
【原創】Linux PCI驅動框架分析(二)
# 背 景 - `Read the fucking source code!` --By 魯迅 - `A picture is worth a thousand words.` --By 高爾基 說明: 1. Kernel版本:4.14 2. ARM64處理器 3. 使用工具:Source Insight
linux驅動開發之蜂鳴器驅動源碼分析(一)
linux 蜂鳴器 驅動 蜂鳴器的驅動源碼在/driver/char/buzzer/x210-buzzer.c文件中,源碼如下#include <linux/module.h> #include <linux/kernel.h> #include <linux
Linux入侵分析(三)清理木馬和問題用戶
入侵分析 雲安全 清除木馬 安全加固 Linux 1.查看哪些用戶擁有/bin/bash權限 cat /etc/passwd 2.檢查常用命令是否被篡改 (1)找到命令文件的路徑(whereis和which) whereis netstat which netstat which net
linux裝置驅動模型 - regmap
1. regmap介紹 regmap主要是為了方便操作暫存器而設計的,它將所有模組的暫存器(包括soc上模組的暫存器和外圍裝置的暫存器等) 抽象出來,用一套統一介面來操作暫存器 比如,如果要操作i2c裝置的暫存器,那麼就要呼叫i2c_transfer介面,要操作spi裝置的暫存
linux裝置驅動模型 - device/bus/driver
在linux驅動模型中,為了便於管理各種裝置,我們把不同裝置分別掛在他們對應的總線上,裝置對應的驅動程式也在總線上找,這樣就提出了deivce-bus-driver的模型,硬體上有許多裝置匯流排,那麼我們就在裝置模型上抽象出bus概念,相應的device就代表裝置,driver表示驅動,