kernel 模塊與簡單 hello 模塊

Kernel 模塊與簡單 hello 模塊

kernel 模塊的簡介

Linux 內核進行擴展時,例如編寫驅動程序、netfilter功能等,最方便的方式是經過編寫模塊,而後加載到內核中。因爲 kernel 模塊已加載到內核,所以若是模塊出現錯誤,將致使內核出錯甚至系統崩潰。因此,通常建議在測試內核模塊時,若是與設備無關的模塊(非驅動程序等),最好是在虛擬機中進行。html

大多數 Linux 發行版本都沒有把 Linux 編譯成一個整個文件,而是把非核心的子系統,如驅動程序等,編譯成 kernel 模塊,並在啓動時加載。模塊的目錄通常是 /lib/modules/<內核版本>/ 目錄下。內核版本號經過 $(uname -r) 獲取。linux

加載內核模塊時,可經過 modprobe (從默認路徑搜索並加載) 或 insmod (指定模塊路徑)shell

# 加載 intel wifi 驅動
sudo modprobe iwlwifi 
# 或
sudo insmod "/lib/modules/$(uname -r)/kernel/drivers/net/wireless/iwlwifi/iwlwifi.ko"

用 lsmod 命令查看已加載的模塊編程

lsmod

而從內核中把模塊刪除則經過 rmmod 命令緩存

sudo rmmod iwlwifi

編寫 hello 示例模塊

內核模塊也是經過 C 編寫和編譯的本機代碼,只是因爲它須要被 Linux 模塊加載框架來載入,所以須要特殊的模塊註冊處理才能生效。內核模塊能直接訪問內核的功能,比通常的 C 編程要更加當心,預防出現 BUG 和安全問題。安全

編寫內核模塊時,使用的頭文件爲 /lib/modules/$(uname -r)/build/include (一般 Linux 頭文件在安裝 kernel-image 同時安裝,在一些發行版上 build 連接到 /usr/src/linux-headers-$(uname-r)/)。框架

先看看一個簡單的 hello 模塊less

/*  
 *  hello.c
 *  簡單的 hello 內核模塊
 */

#include <linux/module.h>       /* 全部模塊使用 module.h */
#include <linux/kernel.h>       /* 包含內核經常使用的函數聲明等 */
#include <linux/init.h>         /* 進行內存初始化和清理 */

MODULE_AUTHOR("fengyc");
MODULE_DESCRIPTION("This is a demo.");
MODULE_VERSION("0.0.1");
MODULE_LICENSE("GPL");

static int __init hello_init(void)
{
    printk(KERN_INFO "Hello, world!\n");
    return 0;
}

static void __exit hello_exit(void)
{
    printk(KERN_INFO "Goodbye, world!\n");
}

module_init(hello_init);
module_exit(hello_exit);

全部的模塊都須要到 module.h 頭文件,使用 module_init() module_exit() 函數來註冊模塊入口和退出處理。這裏的代碼邏輯很簡單,就是在模塊加載時,打印 Hello, world! ,以及在退出時打印 Goodbye, world! (因爲代碼運行在內核空間裏面,不能直接使用用戶空間的 print 函數,而要使用內核中的 printk 函數)eclipse

編譯時經過一個 Makefile 文件進行,把這個 Makefile 文件置於 hello.c 同一目錄下(Makefile 中使用 tab 做爲分隔符函數

obj-m += hello.o

all:
        make -C "/lib/modules/$(shell uname -r)/build" M=$(PWD) modules

clean:
        make -C "/lib/modules/$(shell uname -r)/build" M=$(PWD) clean

如今,經過 make 便可生成模塊 hello.ko。如今可經過 modinfo 命令查看模塊信息

modinfo hello.ko

而後經過 insmod / rmmod 命令加載、卸載模塊,並用 dmesg 查看內核的環形緩存區( kernel ring buffer )的信息( printk 輸出到了這裏)

sudo insmod hello.ko
sudo rmmod hello
dmesg

若是一切順利,就能夠看到 hello.ko 模塊的輸出。而有個這個基本的代碼框架,就能夠繼續深刻,使用 netlink 做爲接口,進行用戶空間與內核空間的通訊,並調用內核的功能,實如今用戶態沒法完成的動做。

p.s. 爲了更好地使用 GUI 的協助,可以使用參考使用 eclipse 內核開發環境 http://blog.chinaunix.net/uid-24512513-id-3183457.html

相關文章
相關標籤/搜索