第四章 Linux核心模組

2021-07-24 11:50:54 字數 4252 閱讀 4736

注:內容大多摘自《linux裝置驅動開發詳解》(第2版)

1.特點:

2.模組程式結構

(1)模組載入函式(一般需要)

(2)模組解除安裝函式(一般需要)

(3)模組許可證宣告(必須)

(4)模組引數(可選)

(5)模組匯出符號(可選)

(6)模組作者等資訊宣告(可選)

3.模組的載入,解除安裝,檢視:

4.printk函式

核心模組中用於輸出的函式是核心空間的printk()而非使用者空間的printf(),printk與printf使用者相似,但前者可定義輸出級別。printk可作為一種最基本的核心除錯手段。參考:printk 使用方法

備註:測試模組例子時,終端沒能輸出printk的輸出資訊,可以通過執行dmesg命令檢視。參考:printk 無法輸出到控制台

1,模組**(建立hello.c):

# include 

# include

static

int hello_init(void)

static

void hello_exit(void)

module_init(hello_init);

module_exit(hello_exit);

module_license("dual bsd/gpl");

2,編譯** (建立makefile檔案):

## 執行uname -r 輸出為 4.2.0-16-generic

kvers = $(shell uname -r)

# kernel modules

obj-m +=hello.o

#specify flags for the module compliation

build: kernel_modules

kernel_modules:

make -c /lib/modules/$(

kvers)/build m=$(

curdir) modules

clean:

make -c /lib/modules/$(

kvers)/build m=$(

curdir) clean

3,在模組**和makefile的當前目錄下執行make命令,生成hello.ko,呼叫insmod hello.ko掛載該模組(可執行lsmod檢視是否掛載成功),呼叫rmmod hello解除安裝該模組。執行dmesg檢視printk的輸出資訊。

moudle_author(author);    #作者

moudle_description(description); #描述

moudle_version(version); #版本

module_device_table(table_info); #裝置表

module_alias(alternate_name); #別名

執行modeinfo 《模組名》可以獲取模組資訊,如modinfo hello.ko。

用module_param(引數名,引數型別,引數讀/寫許可權)為模組定義乙個引數,例子如下:

static

char* book_name = "dissecinting linux device driver";

static

int num = 4000;

module_param(book_name, charp, s_irugo);

module_param(num, int, s_irugo);

# 裝載是執行命令:insmod param.ko book

引數型別可以是byte, short, ushort, int, uinit, long, ulong, charp(字元指標), bool或invbool(布林的反),編譯時會將module_param中宣告的型別和變數定義的型別進行比較,判斷是否一致。

模組載入後,在/sys/module/目錄下面將出現以此模組名命名的目錄。當讀寫許可權為0時,表示此引數不存在sysfs檔案系統下對應的檔案節點;如果不為0,在此模組目錄下回出現parameter目錄,包含一系列以引數命名的檔案節點。許可權在include/linux/stat.h中有定義

使用 s_irugo 引數可以被所有人讀取, 但是不能改變; s_irugo|s_iwusr 允許 root 來改變引數. 注意, 如果乙個引數被 sysfs 修改, 你的模組看到的引數值也改變了, 但是你的模組沒有任何其他的通知. 你應當不要使模組引數可寫, 除非你準備好檢測這個改變並且因而作出反應。

(參考:linux之module_param()函式學習)

嵌入式產品一般不需要建立模組間依賴關係,所以modprobe可以不要,一般也不需要解除安裝模組,所以rmmod也可以不要,但insmod是必須的(在android裝置中嘗試了insmod,rmmod,modinfo,lsmod等命令,都有存在,而modprobe不存在)。一般而言,產品在啟動過程中應該載入模組,在嵌入式產品linux的啟動過程中,最簡單的修改方法是修改啟動過程的rc指令碼(可能是/init.rc檔案),增加insmod /…/***.ko這樣的命令。用busybox做出的檔案系統,通常修改etc/init.d/rcs檔案。

暫時不知道怎麼使用,類似外部函式

參考:匯出符號的意義

1,hello world**:

(1)hello.c**

# include 

# include

static

int hello_init(void)

static

void hello_exit(void)

module_init(hello_init);

module_exit(hello_exit);

module_license("dual bsd/gpl");

(2)makefile檔案

## 執行uname -r 輸出為 4.2.0-16-generic

kvers = $(shell uname -r)

# kernel modules

obj-m +=hello.o

#specify flags for the module compliation

build: kernel_modules

kernel_modules:

make -c /lib/modules/$(

kvers)/build m=$(

curdir) modules

clean:

make -c /lib/modules/$(

kvers)/build m=$(

curdir) clean

2,模組引數例子**:

(1)檔案:book.c

# include 

# include

static

char* book_name = "dissecinting linux device driver";

static

int num = 4000;

static

int hello_init(void)

static

void hello_exit(void)

module_init(hello_init);

module_exit(hello_exit);

module_param(book_name, charp, s_irugo);

module_param(num, int, s_irugo);

module_license("dual bsd/gpl");

(2)檔案:makefile

kvers = $(shell uname -r)

# kernel modules

obj-m +=book.o

#specify flags for the module compliation

build: kernel_modules

kernel_modules:

make -c /lib/modules/$(

kvers)/build m=$(

curdir) modules

clean:

make -c /lib/modules/$(

kvers)/build m=$(

curdir) clean

第四章 Linux核心模組

4.1 linux核心模組簡介 核心模組特點 1 模組本身不被編譯進核心映像中,從而控制核心的大小。2 模組被載入後,它跟核心中的其他部分完全一樣。核心載入命令 lsmod 核心解除安裝命令 rmmod 加強型核心載入函式 modprobe 優點 載入模組所以來的模組。模組之間的依賴關係可以在 li...

第四章Linux核心模組之二(核心模組程式結構)

4.2 linux核心模組程式結構 乙個linux核心模組主要由如下幾個部分組成。1 模組載入函式 當通過insmod或modprobe命令載入核心模組時,模組的載入函式會自動被核心執行,完成本模組的相關初始化工作。2 模組解除安裝函式 當通過rmmod命令解除安裝某模組時,模組的解除安裝函式會自動...

第四章Linux核心模組之五(模組引數)

4.5 模組引數 可以用 module param 引數名,引數型別,引數讀 寫許可權 為模組定義乙個引數,例如下列 定義了1個整型引數和1個字元指標引數 static int book num 4000 module param book num,int,s irugo static char b...