linux進階:設備驅動模型

来源:https://www.cnblogs.com/couvrir/archive/2023/08/16/17635705.html
-Advertisement-
Play Games

為什麼需要設備驅動模型 內核版本發展 2.4版本之前內核沒有統一的設備驅動模型,但是可以用(例如先前的led字元設備驅動實驗,使用前需要手動調用mknod命令創建設備文件,從而進一步控制硬體)。 2.4~2.6版本內核使用devfs,掛載在/dev目錄。需要在內核驅動中創建設備文件(調用devfs_ ...


為什麼需要設備驅動模型

內核版本發展

2.4版本之前內核沒有統一的設備驅動模型,但是可以用(例如先前的led字元設備驅動實驗,使用前需要手動調用mknod命令創建設備文件,從而進一步控制硬體)。

2.4~2.6版本內核使用devfs,掛載在/dev目錄。需要在內核驅動中創建設備文件(調用devfs_register創建設備文件,無需手動mknod命令,需傳入設備文件名),命名過於死板(編譯後驅動對應的設備文件名固定,無法動態修改)。

2.6版本之後內核統一使用sysfs,掛載在/sys目錄。將設備分類、分層次統一進行管理,配合udev/mdev守護進程(開啟自啟,後臺運行,一直監聽內核驅動發出的消息)動態創建設備文件,命令規則自由制定。

sysfs虛擬文件系統在linux系統中體現出設備驅動模型,類似於proc文件系統,總是被掛載在/sys/掛載點上。目錄對應的inode節點會記錄基本驅動對象(kobject),從而將系統中的設備組成層次結構。用戶可以讀寫目錄下的不同文件來配置基本驅動對象(kobject)的不同屬性。

 

設備(device):掛載在某個匯流排的物理設備。

驅動(driver):與特定設備相關的軟體,負責初始化該設備以及提供一些操作該設備的操作方式。

匯流排(bus):負責管理掛載對應匯流排的設備以及驅動。

類(class):對於具有相同功能的設備,歸結到一種類別,進行分類管理。

 

/sys文件目錄記錄著各個設備之間的關係。

/sys/bus是按照匯流排類型分層放置的目錄結構,目錄下的每個子目錄都是已經註冊的匯流排類型。每個子目錄(匯流排類型)包含:devices文件夾drivers文件夾。devices文件夾下是該匯流排類型的所有設備(里的所有設備都是符號鏈接,分別指向真正的設備/sys/devices/)。drivers文件夾下是所有註冊在這個匯流排上的驅動(每個driver子目錄下是一些可以觀察和修改的driver參數)。

/sys/devices目錄下是全局設備結構體系,包含所有被髮現的註冊在各種匯流排上的各種物理設備。一般來說,所有的物理設備都按其在匯流排上的拓撲結構來顯示。

/sys/class是按照設備功能分類的設備模型,目錄下包含所有已經註冊在內核的設備類型。

 

設備驅動模型基本元素

kobject:sysfs的一個目錄,常用來表示基本驅動對象,不允許發送消息到用戶空間。

kset:sysfs的一個目錄,常用來管理kobject,允許發送消息到用戶空間。

kobj_type:目錄下屬性文件的操作介面。

kobject既可以通過parent指針找到上層kobject,也可以通過kset指針找到上層kobject。但上層kobject對象無法遍歷到下層,所以較少使用。

 

kobject結構體

sysfs中每一個目錄都對應一個kobject,kobject結構體存放在內核/include/linux/kobject.h。

struct kobject {
        const char              *name;        //kobject的名稱,同時也是sysfs下的目錄名字
        struct list_head        entry;        //鏈表節點,用於將kobject加入到kset的list_head
        struct kobject          *parent;    //該kobject的上層節點,構建kobject間的層次關係(在sysfs體現為目錄結構)
        struct kset             *kset;        //該kobject所屬的kset對象(可以為NULL),用於批量管理kobject對象
        struct kobj_type        *ktype;        //該kobject的sysfs文件系統相關的操作和屬性
        struct kernfs_node      *sd;         //該kobject在sysfs文件系統中對應目錄項
        struct kref             kref;        //該kobject的引用次數
#ifdef CONFIG_DEBUG_KOBJECT_RELEASE
        struct delayed_work     release;
#endif
        unsigned int state_initialized:1;            //記錄內核對象的初始化狀態
        unsigned int state_in_sysfs:1;                //表示該kobject所代表的內核對象是否在sysfs建立目錄
        unsigned int state_add_uevent_sent:1;        //記錄是否已經向用戶空間發送ADD uevent事件
        unsigned int state_remove_uevent_sent:1;    //記錄是否已經向用戶空間發送REMOVE uevent事件
        unsigned int uevent_suppress:1;                //如果為1,則忽略所有上報的uevent事件
};

由於kobject添加到內核時,需要根據名字註冊到sysfs虛擬文件系統中,之後就不能再直接修改該名字。如果想改,需要調用kobject_rename介面,該介面會主動處理sysfs的相關事宜。
kset如果沒有指定的parent,則會把kset作為parent(kset是一個特殊的kobject)。

uevent提供了“用空空間通知”的功能實現,當內核中有kobject的增刪改等操作時,會通知用戶空間。

 

kset結構體

kset結構體存放在內核/include/linux/kobject.h。

struct kset {
        struct list_head list;                        //指向該kset下所有的kobject組成的鏈表
        spinlock_t list_lock;                        //避免操作鏈表時產生競態的自旋鎖
        struct kobject kobj;                        //該kset自己的kobject(kset是一個特殊的kobject,也會在sysfs中以目錄的形式體現)
        const struct kset_uevent_ops *uevent_ops;    
} __randomize_layout;

uevent_ops為該kset的uevent操作函數集(函數指針)。當kset的某些kobject對象發生狀態變化需要通知用戶空間時,調用其中對應的函數來完成。
當任一kobject需要上報uevent時,都要調用它所屬的kset的uevent_ops,添加環境變數,或者過濾uevent(kset可以決定哪些uevent可以上報)。
因此一個kobject不屬於任一kset時,是不允許發生uevent的。

 

kobj_type結構體

kobj_type結構體存放在內核/include/linux/kobject.h。

struct kobj_type {
        /* 銷毀kobject對象時調用 */
        void (*release)(struct kobject *kobj);
        
        /* 該類型的kobject的sysfs虛擬文件系統操作介面(讀屬性介面show和寫屬性介面store) */
        const struct sysfs_ops *sysfs_ops;
        
        /* 該類型的kobject的attribute表(sysfs的一個文件)。將會在kobject添加到內核時,一併註冊到sysfs中 */
        struct attribute **default_attrs;
        
        const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
        const void *(*namespace)(struct kobject *kobj);
        void (*get_ownership)(struct kobject *kobj, kuid_t *uid, kgid_t *gid);
};

 

 

kobject:驅動的基石

步驟

  1. 創建一個kobject對象
  2. 創建一個sysfs的目錄項(kernfs_node)
  3. 把它們關聯起來

 

重點

  • 關註sysfs目錄項與kobject對象的關聯過程
  • 關註kobject對象預設的屬性文件操作介面

 

kobject主要提供如下功能:

  • 通過parent指針,可以將所有kobject以層次結構的形式組合起來。
  • 使用一個引用計數,來記錄kobject被引用的次數,併在引用計數為0時釋放kobject對象(這是kobject誕生時的唯一功能)。
  • 和sysfs虛擬文件系統配合,將每一個kobject及其特性以文件形式顯示到用戶空間。
  • 在Linux中,kobject幾乎不會單獨存在。它的主要功能就是內嵌在一個大型的數據結構中,為這個數據結構提供一些底層的功能實現。
  • Linux驅動開發者很少會直接使用kobject以及它提供的介面,而是使用構建在kobject之上的設備模型介面。

 

kobject_create_and_add()函數

存放在內核/lib/kobject.c

 

/**
 * kobject_create_and_add - 動態創建一個struct kobject並將其註冊到sysfs
 *
 * @name: 對象的名稱
 * @parent: 這個kobject的父kobject(如果有的話)。
 *
 * 這個函數動態地創建一個kobject結構並將其註冊到sysfs。當您完成此結構時,調用kobject_put(),當不再使用該結構時,該結構將被動態釋放。
 *
 * 如果無法創建kobject,則返回NULL。
 */
struct kobject *kobject_create_and_add(const char *name, struct kobject *parent)
{
        struct kobject *kobj;
        int retval;

        kobj = kobject_create();    //創建並初始化一個kobject對象        
        if (!kobj)
                return NULL;

        retval = kobject_add(kobj, parent, "%s", name);    //sysfs創建一個目錄項並與kobject對象關聯
        if (retval) {
                pr_warn("%s: kobject_add error: %d\n", __func__, retval);
                kobject_put(kobj);
                kobj = NULL;
        }
        return kobj;
}

 

kobject_create_and_add()函數是kobject_create函數和kobject_add函數的組合。整體功能是創建一個名字為“name”的kobject對象,並將其添加到指定的父kobject對象下。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 《quarkus資料庫篇》系列的開篇,編碼實戰最基礎的資料庫增刪改查,資料庫用的是PostgreSQL,在官方demo基礎上進一步精簡,極速入門quarkus資料庫操作 ...
  • ## 一、什麼是異常過濾器? 異常過濾器(**Exception Filters**)是 ASP.NET Core 中用於處理全局異常的機制。它們允許你在發生異常時捕獲、處理和記錄異常,並提供自定義的異常處理邏輯。異常過濾器在整個應用程式範圍內生效,可以用於處理各種異常情況。用於實現常見的錯誤處理策 ...
  • ### VS安裝Avalonia模版 執行以下命令,安裝Avalonia模版(.NET6及之前版本使用--install): ```bash dotnet new install Avalonia.Templates ``` 執行後,會安裝如下模版: ``` 模板名 短名稱 語言 標記 Avalon ...
  • # Nginx反向代理服務流式輸出設置 # 1.問題場景 提問:為什麼我部署的服務沒有流式響應 最近在重構原有的GPT項目時,遇到gpt回答速度很慢的現象。在使用流式輸出的介面時,介面響應速度居然還是達到了30s以上。 # 2.現象分析 分析現象我發現,雖然前端還是流式列印的結果,但是,好像是介面處 ...
  • 為何模塊化 模塊化是一種分治思想,不僅可以分離複雜的業務邏輯,還可以進行不同任務的分工。模塊與模塊之間相互獨立,從而構建一種松耦合的應用程式,便於開發和維護。 開發技術 .Net 6 + WPF + Prism (v8.0.0.1909) + HandyControl (v3.4.0) 知識準備 什 ...
  • 博客推行版本更新,成果積累制度,已經寫過的博客還會再次更新,不斷地琢磨,高質量高數量都是要追求的,工匠精神是學習必不可少的精神。因此,大家有何建議歡迎在評論區踴躍發言,你們的支持是我最大的動力,你們敢投,我就敢肝 ...
  • 全程我在網路上收集這些資料,太零碎了,每一個一看就會,一動手就廢,而且很多都不能實現我白嫖的夢想 我一個人折騰了快一周,現在可以正常訪問手機電腦多端訪問 給個贊再走吧 此處為沒有公網IP(回去折騰你家寬頻去,不知道可以去搜索如何獲得)和功能變數名稱的辦法 簡單的說就是想完全白嫖的那種(甚至雲伺服器(那個有公 ...
  • # 二進位包安裝mysql ## 準備 1.先查看系統中是否已存在mysql,存在將其卸載 ``` rpm -qa mysql rpm -qa mariadb yum remove xxx -y ``` 2.環境清理 清空PATH有關的mysql 註釋掉之前的$PATH 沒有就跳過這步 ``` #e ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...