標籤:linux模組開發 printk
1. 核心模組簡介
Linux 核心的 整 體結構 非 常 龐 大 ,其 包 含 的 組 件也 非 常多 , 如 何使用 需 要 的 組 件 呢?
方 法 一 : 把 所有的 組 件都 編譯 進 核心 文 件, 即 :zImage 或bzImage , 但 這樣會 導 致 兩 個 問 題 : 一是 生 成的 核心 文 件 過大 ;二 是 如果 要 添 加 或 刪 除某 個 組 件, 需 要重 新 編譯 整 個核心
方法二:使用核心模組, 核心 文 件(zImage 或bzImage) 本 身 並不 包 含 某 組 件 , 而 是 在該 組 件 需要 被 使用的 時 候 ,以模組的方式動 態地 添 加 到 正 在 運行 的核心中
2. 核心 模組 具 有 如下特 點 :
? 模組 本 身 並 不 被編譯 進 核心 文 件( zImage 或者bzImage )
? 可以 根 據 需 求 , 在核心 運行 期 間 動 態 的安 裝 或 卸 載
3. 範 例(hello world)
#include <linux/init.h>#include <linux/module.h>static int hello_init(void){printk(KERN_WARNING"Hello, world !\n");return 0;}static void hello_exit(void){printk(KERN_INFO "Goodbye, world\n");}module_init(hello_init);module_exit(hello_exit);
4. 程式結構說明
模組載入函數(必需):安 裝 模組 時 被系統 自 動 調 用的 函 數 , 通 過module_init 宏 來指定,以上例子,指定的載入的函數就是hello_init
模組卸載函數(必須):卸 載 模組 時 被系統 自 動 調 用的 函 數 , 通 過module_exit 宏 來 指定 ,以上例子,指定的載入的函數就是hello_exit
5.pritk函數說明
printk函數和printf的函數實現的功能是一樣的,只不過一個運行在核心態,一個運行在使用者態。
用printk函數列印時候,核心會根據記錄層級,可能把訊息列印到當前的控制台上, 這個控制台通常是一個字元模式的終端、一個串口印表機或是一個並口印表機。這些訊息正常輸出的前提是:日誌輸出層級小於控制台記錄層級(在核心中數字越小優先順序越高)。如果沒有指定列印層級,預設的基本是<4>,即是KERN_WARNING層級,其定製可以再/kernelprintk.c中找到。
記錄層級一共有8個層級,printk的記錄層級定義如下(在include/linux/kernel.h中):
#define KERN_EMERG 0
#define KERN_ALERT 1
#define KERN_CRIT 2
#define KERN_ERR 3
#define KERN_WARNING 4
#define KERN_NOTICE 5
#define KERN_INFO 6
#define KERN_DEBUG 7
通過讀寫/proc/sys/kernel/printk檔案可讀取和修改控制台的記錄層級
#cat /proc/sys/kernel/printk
44 1 7
上面顯示的4個資料分別對應控制台記錄層級、預設的訊息記錄層級、最低的控制台記錄層級和預設的控制台記錄層級
可以修改上面的資料修改控制台的列印層級
備忘:ubuntu 圖形化介面是無法列印到控制台的, printk列印的是控制台,也就是/dev/console,而圖形介面中的終端,其實是把stdin,stdout,stderr三個檔案重新導向了一下。所以printk是無法再圖形介面中的終端中顯示的,當然可以再/var/log/syslog或者用dmesg查看。
6. 模組makefile編寫,makefile名字必須命名為Makefile,否則編譯通過不了,下面這個makefile會被編譯兩次,第一次KERNELRELEASE為空白,去運行
KDIR下面的makefile,接著會重新調用自己的Makefile,編譯成功,產生hello.o,hello.ko兩個檔案
ifneq ($(KERNELRELEASE),)obj-m := hello.o//根據自己的模組修改elseKDIR := /lib/modules/2.6.32-21-generic/build//根據自己lib/modules/下面自己核心版本庫填寫all: make -C $(KDIR) M=$(PWD) modulesclean: rm -f *.ko *.o *.mod.o *.mod.c *.symversendif
7. 載入 模組insmod
insmod hello.ko
可以通過lsmod | grep hello查看自己剛剛載入的核心模組
8. 卸載模組rmmod
rmmod hello
linux中添加核心模組