第四章 Linux內核模塊

注:內容大多摘自《Linux設備驅動開發詳解》(第2版)

Linux內核模塊

1.1 簡介

1.特點:

  • 模塊本身不被編譯入內核映像,從而控制了內核的大小;
  • 模塊一旦被加載,它就和內核中的其他部分完全一樣。

2.模塊程序結構
(1)模塊加載函數(一般需要)
(2)模塊卸載函數(一般需要)
(3)模塊許可證聲明(必須)
(4)模塊參數(可選)
(5)模塊導出符號(可選)
(6)模塊作者等信息聲明(可選)

3.模塊的加載,卸載,查看:

  • 加載:insmod命令
    模塊加載後,在/sys/module/目錄下面將出現以此模塊名命名的目錄。
  • 卸載:rmmod命令
  • 查看:lsmod命令,查看所有加載的內核模塊

4.printk函數
內核模塊中用於輸出的函數是內核空間的printk()而非用戶空間的printf(),printk與printf用戶相似,但前者可定義輸出級別。printk可作爲一種最基本的內核調試手段。參考:printk 使用方法
備註:測試模塊例子時,終端沒能輸出printk的輸出信息,可以通過執行dmesg命令查看。參考:printk 無法輸出到控制檯

1.2,簡單模塊例子

1,模塊代碼(創建hello.c):

# include <linux/init.h>
# include <linux/module.h>

static int hello_init(void)
{
    printk(KERN_EMERG "Hello World enter\n");
    return 0;
}

static void hello_exit(void)
{
    printk(KERN_EMERG "Hello World exit\n");
}

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的輸出信息。

1.3 模塊聲明與描述

MOUDLE_AUTHOR(author);    #作者
MOUDLE_DESCRIPTION(description);    #描述
MOUDLE_VERSION(version);    #版本
MODULE_DEVICE_TABLE(table_info);    #設備表
MODULE_ALIAS(alternate_name);    #別名

執行modeinfo <模塊名>可以獲取模塊信息,如modinfo hello.ko。

1.4 模塊參數

用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()函數學習

1.5 模塊的使用

嵌入式產品一般不需要建立模塊間依賴關係,所以modprobe可以不要,一般也不需要卸載模塊,所以rmmod也可以不要,但insmod是必須的(在Android設備中嘗試了insmod,rmmod,modinfo,lsmod等命令,都有存在,而modprobe不存在)。一般而言,產品在啓動過程中應該加載模塊,在嵌入式產品Linux的啓動過程中,最簡單的修改方法是修改啓動過程的rc腳本(可能是/init.rc文件),增加insmod /…/xxx.ko這樣的命令。用busybox做出的文件系統,通常修改etc/init.d/rcS文件。

1.6 導出符號

暫時不知道怎麼使用,類似外部函數
參考:導出符號的意義

1.7 附錄:

1,Hello World代碼:
(1)hello.c代碼

# include <linux/init.h>
# include <linux/module.h>

static int hello_init(void)
{
    printk(KERN_EMERG "Hello World enter\n");
    return 0;
}

static void hello_exit(void)
{
    printk(KERN_EMERG "Hello World exit\n");
}

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 <linux/init.h>
# include <linux/module.h>

static char* book_name = "dissecinting Linux Device Driver";
static int num = 4000;

static int hello_init(void)
{
    printk(KERN_EMERG "book name:%s\n", book_name);
    printk(KERN_EMERG "book num:%d\n", num);
    return 0;
}

static void hello_exit(void)
{
    printk(KERN_EMERG "Hello World exit\n");
}

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章