Linux驱动开发之模块化加载方法

本文介绍如何编写一个简单的Linux字符设备驱动模块,并详细说明如何通过修改Makefile和Kconfig文件来支持该模块的动态加载。

目录:

一、编写一个最简单的hello.c的驱动程序。

二、把此程序直接放到内核目录下的    ......./char目录中。应该怎样修改Makefile以及Kconfig来实现动态的模块化加载

三、在内核目录下的      ......./char 目录中新建立一个hello_new/的目录(因为在这个字符驱动可能会有较多的源文件以及其他的辅助文件时需要建立一个单独的目录让文件结构更加清楚)



一:编写一个简单的hello_module.c文件

代码如下:

/*
 *  Helloc, World!  我们的第一个模块
 */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
/*
 *    Hello_init 初始化函数
 */
static int hello_init(void)
{
	printk(KERN_ALERT "I bear a charmed life.\n");
	return 0;
}
/*
 *    Hello_exit 退出函数
 */
static void hello_exit(void)
{
	printk(KERN_ALERT "Out Out, brief candle!\n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Chen");
hello_init()函数是模块的入口,模块的所有初始化函数必须符合下面的形式

int my_init(void),因为init函数一般不会在外部调用,所以标记为static。

对于退出函数也必须符合void my_exit(void)的形式。如果文件被静态的编译到内核中,那么退出函数将不包含退出函数,而且永远也不会调用退出函数。

二、把此程序直接放到内核目录下的    ......./char目录中。应该怎样修改Makefile以及Kconfig来实现动态的模块化加载

1)........./char/Makefile文件中的修改:

增加如下语句:     obj-$(CONFIG_HELLO_MODULE)      += hello_module.o    ($(CONFIG_HELLO_MODULE) 主要是与Kconfig中建立内核源码树对应使用)

2)....../char/Kconfig文件中的修改:

增加如下语句:   

config HELLO_MODULE
    tristate "Mini2440 module sample new"
    depends on MACH_MINI2440
    default m if MACH_MINI2440
    help
      Mini2440 module sample new.

这里的HELLO_MODULE与Makefile文件中的CONFIG_HELLO_MODULE后半部分对应。而不是hello_module.c这个文件名字去对应。

其中tristate表示3态的意思,即这个模块有Y、M、N三种状态,在make menuconfig的选项中可以进行选择。Y是表示静态的编译到内核中去。N表示内核不包含此模块。M表示内核把此模块以模块的形式编译到模块中去。

depends on MACH_MINI2440,表示次模块对MACH_MINI2440模块有依赖关系。只有具备了依赖的模块才回出现此模块。如果依赖模块是Y,则此模块可以是Y、M、N,如果依赖模块是M,则此模块可以是M、N,

 default m if MACH_MINI2440表示如果具备这个模块了,默认是模块化编译。

help后面的都属于提示性的化,在make menuconfig的时候,点击help出现的,并且在make menuconfig的时候这个模块的名字为Mini2440 module sample new

3)在做了上面步骤后,进入到.../linux-2.6.32.2这个源代码文件夹,执行make menuconfig,根据需要进行一些选择。再执行make zImage。最后把zImage下载到开发板。

4)在.../linux-2.6.32.2这个源代码文件夹执行make modules,生成hello_module.ko,在把此文件上传到开发板,并且放到/lib/modules/2.6.32.2-FriendlyARM文件夹中,执行modprobe hello_module就可以看到在终端打印出

I bear a charmed life.
再执行modprobe -r  hello_module或则rmmod hello_module就可以看到
Out Out, brief candle!
insmod以及rmmod都仅仅加载指定的模块,不会执行任何依赖性或进一步错误检测。而modprobe不但会加载指定的模块,而且会自动加载任何它所依赖的有关模块。modprobe是最佳的模块加载方式。

三、在内核目录下的      ......./char 目录中新建立一个hello_new/的目录(因为在这个字符驱动可能会有较多的源文件以及其他的辅助文件时需要建立一个单独的目录让文件结构更加清楚)

1)在....../char目录下建立hello/这个文件夹。把原来的hello_module.c文件移动到这个文件中去,并且删除其他的hello_module*的文件。

2)在hello/文件夹下建立Makefile以及Kconfig两个文件。

3)在Makefile文件写入如下内容:

obj-$(CONFIG_HELLO_MODULE)    += hello_module.o

如果以后不是一个源文件时。则这样写

obj-$(CONFIG_HELLO_MODULE)    += hello_module.o

hello_module-objs    :=   hello_module-first.o hello_module-second.o

这样,hello_module-first.c与hello_module-second.c源文件就会自动被编译进去。(其实在Makefile的编写的时候用到了Makefile的潜规则,自动可以生成源文件对应的.o文件)

4)

在Kconfig文件中写入如下内容:

config HELLO_MODULE
    tristate "Mini2440 module sample new second"
    depends on MACH_MINI2440
    default m if MACH_MINI2440
    help
      Mini2440 module sample new second.

这里多了一个second主要目的是和第一次编译的区别,让自己看到,是这次编译成功了,而不是上一次。

5)进入到...../char目录下,修改此目录中的Makefile以及Kconfig

Makefile文件:

先删除在第一次编译过程中添加的东西(当然如果直接使用这种方法进行编译,则不用删除了)

在文件中加入如下语句

obj-$(CONFIG_HELLO_MODULE)    += hello/

Kconfig文件:

先删除在第一次编译过程中添加的东西(当然如果直接使用这种方法进行编译,则不用删除了)

在文件中加入如下语句

source "drivers/char/hello/Kconfig"

6)后面步骤和     二中的     3)   4)步骤一致。

为了确认自己是否,成功,可以修改hello_module.c的输出信息,重新进行模块生成,再放入开发板,进行模块加载,看打印输出信息是否改变了。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值