一個(gè)最簡(jiǎn)單的Linux驅(qū)動(dòng)程序的編譯運(yùn)行
一、背景知識(shí)
可裝載內(nèi)核模塊:為了使系統(tǒng)功能能夠更靈活的擴(kuò)充,Linux支持內(nèi)核的動(dòng)態(tài)擴(kuò)展,即在系統(tǒng)運(yùn)行時(shí)給內(nèi)核增加新的功能(即模塊module)。
模塊:模塊(module)是一段可以被動(dòng)態(tài)鏈接的目標(biāo)代碼(.ko),它可由insmod命令動(dòng)態(tài)的裝載并鏈接到正在運(yùn)行的內(nèi)核。鏈接后,它就成了內(nèi)核的一部分,直到用rmmod命令解除鏈接并卸載。
Linux驅(qū)動(dòng)程序就是一種特殊的可裝載內(nèi)核模塊。
說(shuō)明:本代碼在linux2.6以上測(cè)試運(yùn)行通過(guò)。linux3.*也可。本人用ubuntu12.04,linux內(nèi)核版本linux3.5。
二、編譯內(nèi)核模塊
如何由源碼(.c文件)生成動(dòng)態(tài)鏈接的目標(biāo)代碼(即.ko文件)?
首先寫(xiě)一個(gè)最簡(jiǎn)單的驅(qū)動(dòng)程序源碼:hello.c
[html] view plain copy
- #include <linux/init.h> //聲明頭文件
- #include <linux/module.h>
- //模塊加載函數(shù)
- static int hello_init(void)
- {
- printk(KERN_INFO " Hello World enter\n"); //系統(tǒng)調(diào)用打印函數(shù),類(lèi)似于用戶調(diào)用的printf
- return 0;
- }
- //模塊卸載函數(shù)
- static void hello_exit(void)
- {
- printk(KERN_INFO " Hello World exit\n ");
- }
- module_init(hello_init); //向系統(tǒng)注冊(cè)模塊加載函數(shù)
- module_exit(hello_exit); //向系統(tǒng)注冊(cè)模塊卸載函數(shù)
- MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); //模塊作者等信息聲明,可選
- MODULE_LICENSE("Dual BSD/GPL"); //模塊許可證聲明
- MODULE_DESCRIPTION("A simple Hello World Module"); //模塊描述聲明,可選
- MODULE_ALIAS("a simplest module"); //模塊別名的聲明,可選
將這段程序編譯為hello.ko的步驟:
1、編寫(xiě)makefile文件
[html] view plain copy
- KVERS = $(shell uname -r) #變量KVERS為當(dāng)前l(fā)inux版本值
- obj-m += hello.o
- default:
- make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules
-C后面是linux內(nèi)核源碼樹(shù)目錄,M=后面是源碼目錄
2、在終端下輸入 cd /**/**,找到hello.c源碼所在的目錄
3、在終端輸入 make命令。
4、如圖所示即可生成hello.ko文件。
其他文件是生成的一些中間文件。
三、裝載
加載:在終端輸入insmod命令,模塊加載完成。
注意:如果終端沒(méi)有打印printk語(yǔ)句,在linux系統(tǒng)日志文件/var/log/syslog中查看。
卸載:在終端輸入remmod命令。
打印信息同在日志文件中。
四、一些理論知識(shí)
模塊加載函數(shù):用宏“module_init”指定,它返回整型值。若初始化成功則返回0,若失敗則返回一個(gè)負(fù)值作為錯(cuò)誤碼。
模塊卸載函數(shù)必須用宏“module_exit”指定,無(wú)返回值。
printk用法:
1、printk(KERN_INFO "Hello, world!/n");
2、printk("<6>Hello, world!/n");
***個(gè)參數(shù)指定輸出級(jí)別:分為以下八種:
1、KERN_EMERG 用于緊急消息, 常常是那些崩潰前的消息.
2、KERN_ALERT 需要立刻動(dòng)作的情形.
3、KERN_CRIT 嚴(yán)重情況, 常常與嚴(yán)重的硬件或者軟件失效有關(guān).
4、KERN_ERR 用來(lái)報(bào)告錯(cuò)誤情況; 設(shè)備驅(qū)動(dòng)常常使用 KERN_ERR 來(lái)報(bào)告硬件故障.
5、KERN_WARNING 有問(wèn)題的情況的警告, 這些情況自己不會(huì)引起系統(tǒng)的嚴(yán)重問(wèn)題.
6、KERN_NOTICE 正常情況, 但是仍然值得注意. 在這個(gè)級(jí)別一些安全相關(guān)的情況會(huì)報(bào)告.
7、KERN_INFO 信息型消息. 在這個(gè)級(jí)別, 很多驅(qū)動(dòng)在啟動(dòng)時(shí)打印它們發(fā)現(xiàn)的硬件的信息.
8、KERN_DEBUG 用作調(diào)試消息.