1. 程式人生 > >linux核心程式設計--1模組的裝載和解除安裝

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,有GPLBSD,即模組遵循的開源協議;

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