這篇文章主要解決如何將之前介紹的三個字符設備驅動程序合併爲一個內核模塊,即將null字符設備驅動程序、zero字符設備驅動程序、4k大小的臨時存儲空間的字符設備驅動程序合併爲一個內核模塊,能夠加載到內核模塊中,具體實現過程如下所示:
將之前提到的三個驅動程序放在同一個目錄下,即mydev_null.c、mydev_zero.c、mydev_temp.c和mydev_temp.h文件放在某個文件夾中,然後編寫一個mydev.h文件,內容如下:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#ifdef CONFIG_MODVERSIONS
#define MODVERSIONS
#include <linux/version.h>
#endif
int mydev_null_init(void);
int mydev_zero_init(void);
int mydev_temp_init(void);
void mydev_null_exit(void);
void mydev_zero_exit(void);
void mydev_temp_exit(void);
這個文件主要包括一些頭文件和函數聲明,然後編寫mydev.h文件,如下所示:
#include "mydev.h"
static int __init mydev_init(void)
{
mydev_null_init();
mydev_zero_init();
mydev_temp_init();
return 0;
}
static void __exit mydev_exit(void)
{
mydev_null_exit();
mydev_zero_exit();
mydev_temp_exit();
}
MODULE_AUTHOR("Fang Xieyun");
MODULE_LICENSE("GPL");
module_init(mydev_init);
module_exit(mydev_exit);
這個文件主要說明驅動模塊的初始化和退出所需要進行的操作,由於是合併之前的三個字符設備驅動爲一個內核模塊,所以初始化的時候就調用每個字符設備驅動程序對應的初始化方法,同理,退出也是如此。
同一個普通的c代碼一樣,一個完整的程序有且只有一個入口,即只有一個main方法,而module_init宏相當於驅動模塊的入口,module_exit宏相當於啓動模塊的出口,故在mydev_null.c、mydev_zero.c、mydev_temp.c文件中,需要將如下四行代碼刪除掉。
MODULE_AUTHOR("Fang Xieyun");
MODULE_LICENSE("GPL");
module_init(mydev_init);
module_exit(mydev_exit);
而且要將mydev_null.c、mydev_zero.c、mydev_temp.c文件中的init和exit方法修改爲普通函數,因爲這些函數的聲明在mydev.c中。並且將這三個文件中的包含的頭文件都可以刪除掉,只需要包含mydev.h文件即可(mydev_temp.c文件還需要包含mydev_temp.h文件)。
完成上面的工作之後,接下來就是編寫Makefile文件,其內容如下所示:
obj-m := mydev-mod.o
mydev-mod-objs := mydev.o mydev_null.o mydev_zero.o mydev_temp.o
KERNELDIR := /lib/modules/$(shell uname -r)/build/
PWD:=$(shell pwd)
default:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *.mod.c *mod.o *.ko
之後的加載模塊工作和單個文件就一樣了。。。