linux核心程式設計--1模組的裝載和解除安裝
1. 簡介
linux模組是具有獨立功能的程式,它可以被單獨編譯,但不能獨立執行。它在執行時被連結到核心作為核心的一部分在核心空間執行,這與執行在使用者空間的程序是不同的。模組通常由一組函式和資料結構組成,用來實現一種檔案系統、一個驅動程式或其他核心上層的功能。
也就是說:模組就是整個核心的一部分。但是跟C程式中函式不一樣的一點是,核心模組可以在它所認為適當的時候,插入到核心或者從核心中刪除,而且還不影響核心的正常執行。從而可以在必要的時候對核心進行裁剪,這樣能夠更好的適應於使用者的需求。
2. 核心linux/module.h標頭檔案
按照前文所述,核心linux/module.h標頭檔案定義了模組安裝/解除安裝的相關函式和巨集定義,以下簡述幾個主要的函式和巨集:
1) module_init()函式
此函式以函式指標為引數,用於註冊模組的初始化函式。相當於c程式可以在main函式之前註冊初始化函式。此函式最終為調到__define_initcall函式,將函式指標加入.init段。當用insmod命令載入此模組時,會呼叫此函式。
#define __define_initcall(fn, id) \ static initcall_t __initcall_##fn##id __used \ __attribute__((__section__(".initcall" #id ".init"))) = fn; \ LTO_REFERENCE_INITCALL(__initcall_##fn##id)
2) module_exit()函式
此函式以函式指標作為引數,用於註冊模組的退出(解除安裝)函式。相當於c程式可以用atexit()註冊程序退出回撥。當用rmmod命令解除安裝模組時,呼叫此函式。
3) MODULE_LICENSE/ MODULE_AUTHOR/ MODULE_DESCRIPTION等
此大寫MODULE_開頭的幾個符號為定義在linux/module.h標頭檔案中解釋模組資訊的幾個巨集定義,分別代表:
MODULE_LICENSE--模組的license,有GPL、BSD等,即模組遵循的開源協議;
MODULE_AUTHOR--模組作者
MODULE_DESCRIPTION--模組描述
3. 模組程式碼
以老掉牙的hello world為例,編碼如下模組程式碼如下,假設命令為:module_test.c。其中,printk函式為核心日誌輸出函式,可以列印核心日誌資訊。
//必要的標頭檔案
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
//模組許可證宣告(必須)
MODULE_LICENSE("Dual BSD/GPL");
//模組載入函式(必須)
static int hello_init(void)
{
printk(KERN_ALERT "Hello World enter/n");
return 0;
}
//模組解除安裝函式(必須)
static void hello_exit(void)
{
printk(KERN_ALERT "Hello World exit/n"); return;
}
//模組的註冊
module_init(hello_init);
module_exit(hello_exit);
//宣告模組的作者(可選)
MODULE_AUTHOR("XXX");
//宣告模組的描述(可選)
MODULE_DESCRIPTION("This is a simple example!/n");
//宣告模組的別名(可選)
MODULE_ALIAS("A simplest example");
4. 模組編譯
編寫完模組程式碼後,我們需要對其進行相關操作,變成一個核心模組檔案(.ko檔案)。也就需要寫個Makefile檔案,編譯剛才的模組的程式碼。
obj-m += kernel_test.o
#generate the path
CURRENT_PATH:=$(shell pwd)
#the current kernel version number
LINUX_KERNEL:=$(shell uname -r)
#the absolute path--根據獲取的核心版本拼裝絕對路徑
LINUX_KERNEL_PATH:=/usr/src/linux-headers-$(LINUX_KERNEL)
#complie object
all:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
#clean
clean:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
當make的目標為all時,-C $(KDIR) 指明跳轉到核心原始碼目錄下讀取那裡的Makefile;M=$(PWD) 表明然後返回到當前目錄繼續讀入、執行當前的Makefile。
注意點:
1) Makefile檔案命名為:Makefile,第一個字元大寫;
2) Makefile檔案與原始碼(.c)放在同級目錄;
3) 以root許可權執行make命令----root使用者或普通使用者+sudo。
5. 測試驗證---裝載/解除安裝模組
Linux提供insmod命令裝載核心模組,rmmod命令解除安裝核心模組,相關的還有modinfo(顯示模組的資訊:模組作者、模組license等),lsmod(列出系統所有核心模組)。以下就測試模組的裝載/解除安裝過程中printk列印的訊息----用dmesg命令檢視。-------------我的列印訊息是:” Linux cai ji.------start----”、 “Linux caiji.------end”
6. 參考連結
http://blog.csdn.net/chang198932/article/details/17006537