《linux內核設計與實現》讀書筆記第十七章

第17章 設備與模塊

四種內核成分node

  • 設備類型:在全部 Unix 系統中爲了統一普通設備的操做所採用的分類.
  • 模塊: Linux 內核中用於按需加載和卸載目標碼的機制.
  • 內核對象:內核數據結構中支持面向對象的簡單操做,還支持維護對象之間的父子關係。
  • sysfs :表示系統中設備樹的一個文件系統。

17.1 設備類型

Linux系統中,設備被分爲如下三種類型linux

塊設備網絡

  • 一般縮寫爲 blkdev ,它是可尋址的,尋址以塊爲單位,塊大小隨設備不一樣而不一樣;
  • 支持重定位(seeking )操做,也就是對數據的隨機訪問 塊設備的例子有硬盤、藍光光牒,還有如 Flash 這樣的存儲設備;
  • 經過稱爲「塊設備節點」的特殊文件來訪問的.

字符設備數據結構

  • 字符設備一般縮寫爲 cdev,它是不可尋址的,僅提供數據的流式訪問;
  • 例子有鍵盤、鼠標、打印機,還有大部分僞設備。
  • 經過稱爲「字符設備節點」的特殊文件來訪問的。
  • 與塊設備不一樣,應用程序經過直接訪問設備節點與字符設備交互。

網絡設備dom

  • 網絡設備打破了 Unix 的「全部東西都是文件」的設計原則,它不 是經過設備節點來訪問,而是經過套接字 API 這樣的特殊接口來訪問。 其餘設備
  • 「雜項設備」,是個簡化的字符設備。雜項設備使驅動程序開發者可以很容易地表示一個簡單設備。
  • 「僞設備」的設備驅動是虛擬的,僅提供訪問內核功能而 已。最多見的如內核隨機數發生器(經過/dev/random和/dev/urandom 訪問)、空設備(經過/dev/null 訪問)、零設備(經過/dev/zero訪問)等。

17.2 模塊

17.2.1 Hello,World

一、Linux 內核是模塊化組成的,它容許內核在運行時動態地向其中插入或從中刪除代碼。模塊化

  • 這些代碼(包括相關的子例程、數據、函數人口和函數出口〉被一併組合在 個單獨的二進制鏡像中,即所謂的可裝載內核模塊中,或簡稱爲模塊。

二、支持模塊的好處:函數

  • 基本內核鏡像能夠儘量地小,由於可選的功能和驅動程序能夠利用模塊形式再提供。
  • 模塊容許咱們方便地刪除和從新載入內核代碼,也方便了調試工做。並且當熱插拔新設備時,可經過命令載入新的驅動程序。

三、調用 module_init()實際上不是真正的函數調用,而是一個宏調用,它惟一的參數即是模塊的初始化函數。模塊的全部初始化函數必須符合下面的形式:工具

int my _ init (void) ;ui

17.2.2 構建模塊

構建過程的第一步是決定在哪裏管理模塊源碼。 
構建方式:設計

(1)放在內核派代碼樹中.

  • 把模塊源碼加入到內核源代碼樹中
  • 做爲一個補丁或者是最終把你的代碼合併到正式的內核代碼樹中.

(2)放在內核代碼外.

17.2.3 安裝模塊

用來安裝編譯的模塊到合適的目錄下

make modules install

一般須要以 root 權限運行。

17.2.4 產生模塊依賴性

產生內核依賴關係的信息, root用戶可運行命令

depmod

17.2.5 載入模塊

一、載入模塊最簡單的方法是經過 insmod 命令。

insmod module.ko

二、卸載模塊使用 rmmod 命令,以 root 身份運:

rmmod module

三、via modprobe中插入模塊,須要以 root 身份運行:

modprobe module [ module parameters ]

其中,參數 module 指定了須要載入的模塊各稱,後面的參數將在模塊加載時傳入內核。

17.2.6 管理配置選項

Kconfig 文件:

config FISHING_POLE 
    tristate  "Fish Master 3000  support"
    default  n 
    help 
        If you say Y here,  support for the  Fish  Master  3000  wi th computer interface will  be compiled into  the kernel  and  accessible via a device node . You can  also  say M here  and  the  driver will  be  built as  a 
        module named fishing.ko. 
        If  unsure,  say N.
  • 配置選項第一行定義了該選項所表明的配置目標。注意 CONFIG_ 前綴並不須要寫上。
  • 第二行聲明選項類型爲住istate,也就是說能夠編譯進內核(Y),也可做爲模塊編譯(M),或者乾脆不編譯它(N)。若是編譯選項表明的是一個系統功能,而不是一個模塊,那麼編譯選項將用 bool 指令代替往istate,這說明它不容許被編譯成模塊。處於指令以後的引號內文字爲該選項指定了名稱。
  • 第三行指定了該選項的默認選擇,這裏默認操做是不編譯它(則。也能夠把默認選擇指定爲編譯進內核飛凹,或者編譯成一個模塊(M)。對驅動程序而言,默認選擇一般爲不編譯進內核(N)。
  • Help 指令的目的是爲該選項提供幫助文檔。各類配置工具均可以按要求顯示這些幫助。由於這些幫助是面向編譯內核的用戶和開發者的,因此幫助內容簡潔扼要。通常的用戶一般不會編譯內核,但若是他們想試試,每每也能理解配置幫助的意思。

17.2.7 模塊參數

全部宏須要包含<linux/module.h>頭文件。

17.2.8 導出符號表

在內核中,導出內核函數須要使用特殊的指令:

EXPORT_ SYMBOL()和 EXPORTSYMBOLGPL()

17.3 設備模型

統一設備模型 :

設備模型提供了一個獨立的機制專門來表示設備,並描述其在系統中的拓撲結構,從而使得系統具備如下優勢:

  • 代碼重複最小化.
  • 提供諸如引用計數這樣的統一機制。
  • 能夠列舉系統中全部的設備,觀察它們的狀態,而且查看它們鏈接的總結.
  • 能夠將系統中的所有設備結構以樹的形式完整、有效地展示出來一一包括全部的總統和內部鏈接。
  • 能夠將設備和其對應的驅動聯繫起來,反之亦然。
  • 能夠將設備按照類型加以歸類,好比分類爲輸入設備,而無需理解物理設備的拓撲結構.
  • 能夠沿設備樹的葉子向其根的方向依次遍歷,以保證能以正確順序關閉各設備的電源。

17.3.1 kobject

設備模型的核心部分就是 kobject,它自 struct kobject 結構體表示,定義於頭文件<linux/kobject.b>中。

17.3.2 ktype

ktype 的存在是爲了描述一族kobject 所具備的廣泛特性.

17.3.3 kset

kset 是 kobject 對象的集合體。把它當作是一個容器,可將全部相關的 kobject 對象,好比「所有的塊設備」置於同一位置。

17.3.4 kobject、ktype和kset的相互關係

kobject,由 struct koject 表示。 kobject 爲咱們引入了諸如引用計數、父子關係和對象名稱等基本對象道具,而且是以一個統一的方式提供這些功能。

17.3.5 管理和操做kobject

使用 kobjcet 的第一步須要先來聲明和初始化。 kobject 經過函數ko均ect_init 進行初始化,該函數定義在文件 <linux/kobject.h>中 :

void kobjectinit(struct kobject •kobj, struct kobjtype •ktype);

  • 第一個參數就是須要初始化的 kobject 對象,在調用初始化函數前, kobject 必須清空。
  • 這個工做每每會在 kobject 所在的上層結構體初始化時完成。
  • 若是 kobject 未被清空,那麼只須要調用 memset().

17.3.6 引用計數

  • 增長引用計數稱爲得到對象的引用,減小引用計數稱爲釋放對象的引用。
  • 當引用計數跌到零時,對象即可以被撤銷,同時相關內存也都被釋放。

17.4 sysfs

  • sysfs文件系統是個處於內存中的虛擬文件系統
  • 它爲咱們提供了 kobject 對象層次結構的視圖。
  • 幫助用戶能以一個簡單文件系統的方式來觀察系統中各類設備的拓撲結構。

17.4.1 sysfs中添加和刪除kobject

函數都定義於文件 lib/kobject.c 中,聲明於頭文件<linux/kobject.b>中。

17.4.2 向sysfs中添加文件

一、 默認屬性

  • 默認的文件集合是經過 kobject 和 kset 中的 ktype 字段提供的。所以全部具備相同類型的 kobject 在它們對應的 sysfs 目錄下都擁有相同的默認文件集合.

二、建立新屬性

  • 在sysfs 中建立一個符號鏈接:

int sysfscreatelink(struct kobject kobj, struct kobject target, char name);

三、刪除新屬性 - 刪除一個屬性需經過函數sysfsremove file() 完成:

void sysfsremovefile (struct kobject kobj, const struct attribute attr);

  • 由sysfs_ creat_ link()建立的符號鏈接可經過刪除:

void sysfsremovelink(struct kobject kobj , char name);

17.4.3 內核事件層

一、內核事件由內核空間傳遞到用戶空間須要通過 netlink. netlink 一個用於傳送網絡信息的多點傳送套接字。

二、在內核代碼中向用戶空間發送信號使用函數 kobject uevent():

int kobject_uevent(struct kobject *kobj,enum kobject_ action action);

  • 第一個參數指定發送該信號的 koject 對象。實際的內核事件將包含該 koject 映射到 sysfs路徑。
  • 第二個參數指定了描述該信號的「動做」或「動詞」。
相關文章
相關標籤/搜索