日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

前言:

linux 內(nèi) 核 模 塊 全 稱 為 “ 動 態(tài) 可 加 載 內(nèi) 核 模 塊 (Loadable Kernel Module,LKM)”,是系統(tǒng)內(nèi)核向外部提供的功能插口。作為宏內(nèi)核結(jié)構(gòu),Linux 內(nèi)核具有效率高的特點,但也有可擴展性和可維護(hù)性相對較差的不足,Linux 提供模塊機制正是彌補這一缺陷。

模塊是具有獨立功能的程序,它可以被單獨編譯,但不能獨立運行。模塊在運行時被鏈接到內(nèi)核作為內(nèi)核的一部分在內(nèi)核空間運行,這與運行在用戶控件的進(jìn)程是不同的。模塊通常有一組函數(shù)和數(shù)據(jù)結(jié)構(gòu)組成,用來實現(xiàn)某種文件系統(tǒng)、驅(qū)動程序或其它內(nèi)核上層功能。

本文將介紹如何編寫一個簡單的內(nèi)核模塊以及如何傳遞參數(shù)給此模塊。

一、 編寫一個簡單的內(nèi)核模塊

1.編寫模塊程序

編寫如下簡單代碼,本示例中代碼文件命名“hello_module.c”。

//hello_module.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

static int __init hello_init(void){
   printk("This is hello_module, welcome to Linux kernel n");
   return 0;
}

static void __exit hello_exit(void){
   printk("see you next time!n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mr Q");
MODULE_DESCRIPTION("hello kernel module");
MODULE_ALIAS("hello");

以上代碼解釋如下:

(1) #include <linux/module.h>:必須。module.h 頭文件包含了對模塊的結(jié)構(gòu)定義以及模塊的版本控制,任何模塊程序的編寫都要包含這個頭文件;

(2) #include <linux/kernel.h>:kernel.h 包含了常用的內(nèi)核函數(shù),如以上程序中的 printk()函數(shù);

(3) #include <linux/init.h>:必須。init.h 包含了 module_init()和 module_exit()函數(shù)的聲明;

(4) module_init():必須。模塊加載函數(shù),加載模塊式該函數(shù)自動執(zhí)行,進(jìn)行初始化操作;

(5) module_exit():必須。模塊卸載函數(shù),卸載模塊時函數(shù)自動執(zhí)行,進(jìn)行清理操作;

(6) MODULE_LICENSE():表示模塊代碼接受的軟件許可協(xié)議。Linux 內(nèi)核是使用 GPL V2 的開源項目,其要求所有使用和修改了 Linux 內(nèi)核代碼的個人或組織都有義務(wù)把修改后的源代碼公開,這是一個強制的開源協(xié)議,所以一般編寫驅(qū)動代碼都需要顯示的聲明和遵循本協(xié)議,否則內(nèi)核 UI 發(fā)出被污染的警告;

(7) MODULE_AUTHOR():描述模塊的作者信息;

(8) MODULE_DESCRIPTION():簡單描述模塊的用途、功能介紹等;

(9) MODULE_ALIAS():為用戶控件提供的別名;

(10) printk():內(nèi)核輸出函數(shù),默認(rèn)打印系統(tǒng)文件 “ /var/log/kern.log”的內(nèi)容。

2. 編譯內(nèi)核模塊

編寫 Makefile 文件,文件名必須為“Makefile”

obj-m := hello_module.o

KERNELBUILD := /lib/modules/$(shell uname -r)/build
CURRENT_PATH := $(shell pwd)

all:
	make -C $(KERNELBUILD) M=$(CURRENT_PATH) modules

clean:
		make -C $(KERNELBUILD) M=$(CURRENT_PATH) clean

以上代碼解釋如下:

(1) obj-m := <模塊名>.o:定義要生成的模塊名稱

(2) KERNELBUILD := /lib/modules/$(shell uname -r)/build :

KERNELBUILD 為自定義名稱,用于指向正在運行 Linux 的內(nèi)核編譯目錄,其中“uname -r”標(biāo)識顯示對應(yīng)的內(nèi)核版本;

(3) CURRENT_PATH := $(shell pwd):CURRENT_PATH 為自定義名稱,用于指向當(dāng)前當(dāng)前目錄;

(4) all:編譯執(zhí)行的動作

(5) clean:zhixing make clean 需要的動作。“make clean”用于清除上次的 make 命令所產(chǎn)生的 object 文件(后綴為“.o”的文件)及可執(zhí)行文件。

3.編譯

將以上兩個文件(hello_module.c 和 Makefile)保存于同一目錄下,將上文中代碼存放在路徑為“/code/hellomodule/”,編譯需在文件保存目錄中進(jìn)行。

教你編寫你的第一個Linux 內(nèi)核模塊“hello_module”

 

編譯成功后,可看到生成的 hello_module.ko 目標(biāo)文件

教你編寫你的第一個Linux 內(nèi)核模塊“hello_module”

 

4.檢查編譯模塊

可通過 file 命令檢查編譯的模塊是否正確,可以看到 x86-64 架構(gòu)的 elf文件,說明編譯成功:

教你編寫你的第一個Linux 內(nèi)核模塊“hello_module”

 

也可通過 modinfo 命令進(jìn)一步檢查 :

教你編寫你的第一個Linux 內(nèi)核模塊“hello_module”

 

5.插入模塊

通過 insmod 命令插入模塊,完成插入后可通過 lsmod 命令查看當(dāng)前模塊是否已經(jīng)被加載到系統(tǒng)中:

教你編寫你的第一個Linux 內(nèi)核模塊“hello_module”

 

系統(tǒng)加載模塊后,也會在“/sys/module”目錄下新建以模塊名命名的目錄 :

教你編寫你的第一個Linux 內(nèi)核模塊“hello_module”

 

6.查看輸出

因 本 演示 中 prink()采 用 默認(rèn) 輸出 等級 ,可 通 過“ dmesg” 或“ tail /var/log/kern.log”命令查看輸出結(jié)果。

教你編寫你的第一個Linux 內(nèi)核模塊“hello_module”

 

“ tail /var/log/kern.log”命令查看輸出結(jié)果:

教你編寫你的第一個Linux 內(nèi)核模塊“hello_module”

 

7. 卸載模塊

卸載模塊,可通過“rmmod 模塊名”實現(xiàn),通 過“ tail /var/log/kern.log”命令查看輸出結(jié)果。

教你編寫你的第一個Linux 內(nèi)核模塊“hello_module”

 

二、 模塊參數(shù)

1.說明

Linux 內(nèi)核提供一個宏來實現(xiàn)模塊的參數(shù)傳遞

#define module_param(name, type, perm) 
module_param_named(name, name, type, perm)

#define MODULE_PARM_DESC(_parm, desc) 
_MODULE_INFO(parm, _parm, #_parm ":" desc);

module_param()宏由 3 個參數(shù)組成,name 表示參數(shù)名,type 表示參數(shù)類型,perm 表示參數(shù)讀寫權(quán)限。MODULE_PARM_DESC()宏提供參數(shù)的簡單說明,參數(shù)類型可為 byte、short、int、long、char、bool 等類型;perm 指定在 sysfs 中相應(yīng)文件的訪問權(quán)限,如設(shè)置為 0 則不會出現(xiàn)在 sysfs 文件系統(tǒng)中,設(shè)置為 0644 標(biāo)識 root 用戶可修改本參數(shù)。

static int debug = 1;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "enable debugging information");

#define dprintk(args...) if(debug){printk(KERN_DEBUG args);}

如上述實際代碼所示(driver/misc/altera-stap1/altera.c),實際定義模塊參數(shù) debug,類型是 int,訪問權(quán)限是 0644。參數(shù)用途是大概調(diào)試信息,實際內(nèi)核編程中常用此方法進(jìn)行內(nèi)核調(diào)試。

2.開始動手

修改上文中的“hello_module.c”文件,改為以下內(nèi)容:

//hello_module.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

static int debug = 1;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "debugging information");

#define dprintk(args...) if(debug){printk(KERN_DEBUG args);}
static int myparm = 10;
module_param(myparm, int, 0644);
MODULE_PARM_DESC(myparm, "kernel module parameter experiment.");


static int __init parm_init(void){
   dprintk("my linux kernel module init.n");
   dprintk("module parameter = %dn", myparm);

   return 0;
}

static void __exit parm_exit(void){
   printk("see you next time!n");
}

module_init(parm_init);
module_exit(parm_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mr Q");
MODULE_DESCRIPTION("kernel module paramter experiment");
MODULE_ALIAS("myparm");

make編譯,裝載模塊,并查看輸出:

教你編寫你的第一個Linux 內(nèi)核模塊“hello_module”

 

通過查看日志信息,可發(fā)現(xiàn)輸出以上程序中 參數(shù) 的默認(rèn)值。

卸載模塊,賦值重新加載模塊,修改參數(shù) myparm 值為 116:

insmod parm_module.ko myparm=116  
教你編寫你的第一個Linux 內(nèi)核模塊“hello_module”

 

通過查看日志信息,可發(fā)現(xiàn) 參數(shù) 值已經(jīng)改變。

分享到:
標(biāo)簽:Linux
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達(dá)人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定