看了那麼多理論知識,可能還是一頭霧水,是啊,純理論分析本來就不好理解。為了更好的理解Linux內核各種內部機制以及其運用,在接下來的學習中將采用理論+實驗+源碼注釋的方式進行。包括算法、原理的實驗,內核的局部擴展與修改等。Linux內核編程有很多方法,最方便的方式是使用內核提供的模塊編程機制,另一種方式是以補丁的方式,這種方式只需要編譯一次內核,當然也可以直接修改內核源碼,但是每次修改後都需要重新編譯、引導、重啟,很麻煩,也很費時。首先,我們看看最方便快捷的一種方式——LINUX內核中模塊編程機制。
還是從程序員的哪個起步程序hello world開始,但是我們這裡比一般的hello world稍微復雜一點,用兩個hello world程序。
文件hello.c
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
-
- MODULE_LICENSE("GPL");
- extern int hello_data;
-
- static int hello_init(void)
- {
- printk(KERN_ERR "hello,kernel!,this is hello module\n");
- printk(KERN_ERR "hello_data:%d\n",++hello_data);
- return 0;
- }
-
- static void hello_exit(void)
- {
- printk(KERN_ERR "hello_data:%d\n",--hello_data);
- printk(KERN_ERR "Leave hello module!\n");
- }
- module_init(hello_init);
- module_exit(hello_exit);
-
- MODULE_AUTHOR("Mike Feng");
- MODULE_DESCRIPTION("This is hello module");
- MODULE_ALIAS("A simple example");
對應的Makefile文件:
- obj-m +=hello.o
- CURRENT_DIR:=$(shell pwd)
- KERNEL_DIR:=$(shell uname -r)
- KERNEL_PATH:=/usr/src/kernels/$(KERNEL_DIR)
-
- all:
- make -C $(KERNEL_PATH) M=$(CURRENT_DIR) modules
- clean:
- make -C $(KERNEL_PATH) M=$(CURRENT_DIR) clean
文件hello_h.c:
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
-
- MODULE_LICENSE("GPL");
- static unsigned int hello_data=100;
- EXPORT_SYMBOL(hello_data);
-
- static int hello_h_init(void)
- {
- hello_data+=5;
- printk(KERN_ERR "hello_data:%d\nhello kernel,this is hello_h module\n",hello_data);
-
- return 0;
- }
-
- static void hello_h_exit(void)
- {
- hello_data-=5;
- printk(KERN_ERR "hello_data:%d\nleave hello_h module\n",hello_data);
- }
-
- module_init(hello_h_init);
- module_exit(hello_h_exit);
- MODULE_AUTHOR("Mike Feng");
對應的Makefile
- obj-m+=hello_h.o
- CURRENT:=$(shell pwd)
- KERNEL_PATH:=/usr/src/kernels/$(shell uname -r)
-
- all:
- make -C $(KERNEL_PATH) M=$(CURRENT) modules
- clean:
- make -C $(KERNEL_PATH) M=$(CURRENT) clean
可見,我們在hello_h.c中定義了一個靜態變量hello_data,初始值為100,並把他導出了,在hello.c中使用了該變量。這樣給出例子,後面我們會看到,是為了說明模塊依賴。