原文地址:Kernel Module實戰指南(一):Hello World!linux
對於習慣了平時在Linux上進行C應用程序開發的你,是否想窺探一下底層的世界?
對於對Linux Kernel源碼無從下手的你,是否但願有一個簡易的方法?
是的,這裏有一個地方,可讓你輕鬆的編寫和調試Linux Kernel Code。
這個就是我將要介紹的Linux Kernel Module,即Linux內核模塊。shell
Linux Kernel Module是一段能夠在運行時被加載到Linux Kernel中的代碼,能夠使用Kernel Functions。Linux Kernel Module的用途很廣,最多見的例子就是Device Driver,也就是設備驅動程序。
若是沒有Linux Kernel Module,每一行修改Kernel代碼,每個新增的Kernel功能特性,都須要從新編譯Kernel,大大浪費了時間和效率。bash
在bash下輸入:函數
$ lsmod Module Size Used by nls_utf8 16384 1 isofs 30960 1 ...
或者直接在bash下查看:ui
$ cat /proc/modules
閒話少說,開始編寫咱們的第一個Kernel Module,直接上代碼,hello-world.c:命令行
#include <linux/kernel.h> #include <linux/module.h> int init_module(void) { printk(KERN_INFO "Hello World!\n"); return 0; } void cleanup_module(void) { printk(KERN_INFO "Bye World!\n"); }
內核中打印函數和應用打印函數略微不一樣,printf()是glibc的函數,內核中使用printk()。實際上printk()的設計並非爲了打印,而是爲了記錄,根據配置不一樣,內容可能由syslogd或者klogd打印到/var/log/messages中,或者打印到你的console中。
編譯的話,和應用層代碼使用的gcc或者g++不一樣,Kernel Module使用Makefile,或者kbuild。下面是Makefile文件:設計
obj-m += hello-world.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-world.ko,以及其餘的臨時文件。
經過modinfo來查看module信息,在命令行輸入:code
$ modinfo hello-world.ko filename: hello-world.ko ...
如今沒有什麼信息,彆着急,後面會介紹如何將信息(author, license等)寫到Kernel Module中。
運行咱們的Kernel Module,在命令行輸入:開發
$ insmod hello-world.ko
若是提示權限不夠,輸入:
$ sudo insmod hello-world.ko
執行完畢後,可能在console上不會顯示任何結果。還記得前面提到的嗎?咱們須要查看/var/log/messages,最簡單的方法是在命令行輸入:
$ dmesg ... [26484.975093] Hello World!
好了,咱們卸載模塊,一樣在命令行輸入:
$ rmmod hello-world.ko
若是提示權限不夠,輸入:
$ sudo rmmod hello-world.ko
執行完畢後,可能在console上不會顯示任何結果。一樣查看/var/log/messages:
$ dmesg ... [26484.975093] Hello World! [26739.017345] Bye World!
咱們先簡單包裝一下Hello World的Code,讓他看上去稍微豐富一點:
#include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> static int __init init_my_module(void) { printk(KERN_INFO "Hello, my module!\n"); return 0; } static void __exit exit_my_module(void) { printk(KERN_INFO "Bye, my module!\n"); } module_init(init_my_module); module_exit(exit_my_module); MODULE_LICENSE("GPL"); MODULE_AUTHOR("csprojectedu");
這裏咱們使用了linux/init.h中提供的宏__init和__exit,解放咱們的函數名,再也不沿用蹩腳的init_module()和cleanup_module()了。
Makefile仍是沿用以前的:
obj-m += my_module.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
經過modinfo來查看module信息,在命令行輸入:
$ modinfo my_module.ko filename: my_module.ko author: csprojectedu license: GPL ...
是否是多了author和license?insmod的時候也再也不報缺乏license的警告了吧。
經過最簡單的hello-world.c和Makefile(真的沒有比這個更簡單的代碼了),介紹瞭如何編寫咱們的第一個Kernel Module。動手作一作吧,你已經邁向了內核世界的第一步。