如何把自己的模塊編譯到內核中

 如何把一個自己寫的外部驅動模塊編譯添加到內核中

有時候還是需要把自己寫的驅動模塊添加到內核中去編譯成一個整體,這樣很容易YY,我靠,我也能在內核目錄里加代碼了

首先選一個典型的例子,一個外部驅動模塊,需要傳入兩個參數,然後通過cat /proc/result 查看他們的和
/*
test_inline_driver.c
這是一個例子,把模塊參數val1+ val2的和通過 cat /proc/result 顯示出來
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>

#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>

#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/stat.h>
#include <linux/proc_fs.h>

struct proc_dir_entry *sumproc_result_fp=NULL;

int val1=0,val2=0;

module_param(val1,int,S_IRUGO);
module_param(val2,int,S_IRUGO);

MODULE_DESCRIPTION("My kernel module");
MODULE_AUTHOR("deep_pro");
MODULE_LICENSE("GPL");

int read_result(char *page,char **start,off_t off,int count,int *eof,void *data_unused)
{
char *buf;
buf=page;
buf+=sprintf(buf,"result %d+%d = %d /n",val1,val2,val1+val2);
*eof=1;
return buf-page;
}


static int test_inline_driver_init_module(void)
{
printk( KERN_DEBUG "Module test_inline_driver init/n" );
sumproc_result_fp=create_proc_entry("result",S_IFREG|S_IRUSR,NULL);
if(sumproc_result_fp!=NULL)
{
sumproc_result_fp->read_proc=read_result;
}
return 0;
}

static void test_inline_driver_exit_module(void)
{
printk( KERN_DEBUG "Module test_inline_driver exit/n" );
remove_proc_entry("result",0);
}



#ifndef MODULE
static int __init get_val(char *str)
{
int ints[10];
str=get_options(str,ARRAY_SIZE(ints),ints);
if(ints[0]==2)
{
val1=ints[1];
val2=ints[2];
}
return 1;
}
__setup("getval=",get_val);
__initcall(test_inline_driver_init_module);
#else
module_init(test_inline_driver_init_module);
#endif
module_exit(test_inline_driver_exit_module);


可以看到,在代碼上有兩個要求
首先,編譯進內核的模塊就不能靠module_init來啓動了,需要__initcall
其次,編譯進內核的模塊不能靠insmod命令這樣的方式傳入參數,只能通過__setup讀取linux啓動參數
所以需要靠#ifndef MODULE 來判斷當前模塊是編譯成外部模塊還是直接編譯進內核

然後就需要修改對應驅動目錄下的Kconfig和Makefile文件,這個例子放在/linux-2.6.29/drivers/char 目錄下
對於Kconfig,打開後在靠前的位置進行如下修改後的前20行

#
# Character device configuration
#

menu "Character devices"

config test_inline_driver
tristate "test_inline_driver is my test"
---help---
this is a sample driver,to test building a driver into kernel


config VT
bool "Virtual terminal" if EMBEDDED
depends on !S390
select INPUT
default y
---help---
If you say Y here, you will get support for terminal devices with
display and keyboard devices. These are called "virtual" because you
can run several virtual terminals (also called virtual consoles) on

其中加粗的是自己添加的內容,config選項定義了符號值
tristate命令可以選擇是Y還是M

這樣的修改,make menuconfig可以看到
如何把一個自己寫的外部驅動模塊編譯添加到內核中 - Jesse Rei - Jesse Rei 的博客(優柔寡斷)

接下來修改Makefile,修改後前20行
#
# Makefile for the kernel character device drivers.
#

#
# This file contains the font map for the default (hardware) font
#
FONTMAPFILE = cp437.uni

obj-y     += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o

obj-$(CONFIG_test_inline_driver) += test_inline_driver.o

obj-$(CONFIG_LEGACY_PTYS)    += pty.o
obj-$(CONFIG_UNIX98_PTYS)    += pty.o
obj-y                += misc.o
obj-$(CONFIG_VT)        += vt_ioctl.o vc_screen.o selection.o keyboard.o
obj-$(CONFIG_CONSOLE_TRANSLATIONS) += consolemap.o consolemap_deftbl.o
obj-$(CONFIG_HW_CONSOLE)    += vt.o defkeymap.o
obj-$(CONFIG_AUDIT)        += tty_audit.o

其中的加粗的一行是自己加的
很容易理解,obj-y是無條件一定會編譯進內核的,obj-$(CONFIG_xxxx)是編譯成xxxx.o但會不會鏈接進內核得看make menuconfig的選擇的,obj-m就一定會編譯成外部模塊

好了,準備工作完成,make之後修改啓動linux參數,在最後加上 getval=1,2
如mini2440是noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0 getval=1,2
測試結果
發佈了57 篇原創文章 · 獲贊 15 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章