Linux内核驱动模块编写(Hello,World)

 

我觉得自己的目标很混乱,总是看这个又看那个.虽说这个习惯不好,可是也增加了许多见识.

今天尝试编写内核模块,写了一个hello,world,结果弄了1个小时。

主要参考了网上的人的说明,结果发现尽信书不如无书,很多人说的都不是很仔细,我觉得这对于初学者来说,很不好。

大家贴出来的东西,不仅仅给自己也是给别人,所以有时候一定要严谨,否则很可能误导别人。

首先贴出代码 


 1// 这两个头文件包含相应宏定义
 2#include <linux/init.h>
 3#include <linux/module.h>
 4// 告知内核,这是free模块
 5MODULE_LICENSE("GPL");
 6
 7// 模块进入函数
 8static int __init hello_init(void){
 9        printk(KERN_ALERT "Hello World/n");
10        return 0;
11}

12
13// 模块退出函数
14static void __exit hello_exit(void){
15        printk(KERN_ALERT "Hello World exit/n");
16}

17
18// 初始化
19module_init(hello_init);
20// 退出 
21module_exit(hello_exit);
22// 作者声明
23MODULE_AUTHOR("Di Zhuang");
24MODULE_DESCRIPTION("A simple Hello World Module");
25MODULE_ALIAS("a simplest module");

 那么代码是很简单的,问题出现在编译上,网上很多人说要在编译的内核下编译,这个我不太懂,可能是编译后生成了我们所需要的文件?我是按照linux源代码Documention目录下面kbuild下的modules.txt和网上另一位仁兄的makefile写的,之前我很多人说用gcc -D__KERNEL__ -DMODULE -DLINUX -I{"你的linux源程序目录"} -c -o 这种编译的,结果错误一大堆,上网搜索,结果也没谁说出准确的解决方案,都是说自己解决,可我觉得这可能和不同的环境有关,很可能就是你的环境适合你的解决办法,为什么没人能够说出一种通用的解决办法。上面的办法貌似听说在2。4内核好用,我2.6还没搞明白,估计这东西在2.6上不适合吧。

那么还是采用2.6官方文档和网上成功编译人的方案,那就是写个Makefile,写好编译路径,以及模块编译后放置的路径。insmod貌似总从/lib/modues/目录下加载模块的,至于make工具如何保证我们编译的模块一定能够被正确加载,这个我暂时没研究,以后研究一下。

下面把Makefile文件贴出来

ifneq ($(KERNELRELEASE),)
obj - m : =  {你要编译目标文件的名.o}
else
# modules所在目录
KERNELDIR : =   / lib / modules / `uname  - r` / build
default :
        $(MAKE)  - C $(KERNELDIR) M = `pwd` modules
endif

 对于这段语句,说实话,我能明白,可不太知道为什么要if else 这么写,谁能解答一下? 

写好之后,运行make,然后就会发现你当前目录多了很多文件,其中一个就是.ko文件,这个就是我们需要的。

好,现在运行insmod ./你的ko文件

网上很多人会说打出什么打印语句,结果我在控制台什么也没看见,后来才知道,这个需要用dmesg | tail命令来看

好像insmod打印重定向了??????

之后你在运行rmmod ./你的ko文件

OK , 大功告成。

说来,一个Hello,World模块书写真老费时间。。。。。。。。 

 

///

(1) 模块动态加载驱动方式

在内核源码的“drivers/char/”目录下新建一个名为“hello .c”的文件,内容如下:

 

 

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/init.h>

 

MODULE_LICENSE ("GPL");

 

static int __init hello_init (void)

{

   printk (KERN_INFO "Hello world/n");

   return 0;

}

 

static void __exit hello_exit (void)

{

   printk (KERN_INFO "Goodbye world/n");

}

 

module_init (hello_init);

module_exit (hello_exit);

 

   修改Makefile里面的内核源码包的路径,这里我们必须用到一个已经编译好的内核的源码

这里我们用了

KERNELDIR ?= /mnt/mengyang/source/kernel/linux-2.6.33

根据自己的实际情况修改,一定确保你的内核可以编译通过,内核可以正常运行!

在命令行里运行make命令,顺利的会生成*.ko文件。将*.ko文件复制到nfs目录,或是其他的存储设备。

在命令行里运行插入模块的命令

insmod *.ko

顺利的可以看到init函数将会被调用。

同样,运行

rmmod *.ko

顺利的可以看到clean函数被执行了。

执行上面命令时,可能报错误rmmod: chdir(2.6.33.2-TE2440): No such file or directory

这是由于busybox 1.13.1导致的,,原来是现在的内核模块在插入卸载时都会要转到/lib/modules/内核版本号目录里。 所以只要建立这个目录并且把要使用的模块*.ko文件复制到这个目录就行了。

2)静态的加载驱动

在内核源码中添加对hello 驱动的支持

修改drivers/char/目录下的“Kconfig”文件,在行添加如下内容:(红色部分所示)

#

# Character device configuration

#

menu "Character devices"

config CCTE_HELLO

tristate "CCTE2440 Hello Driver"

depends on ARCH_S3C2440

help

CCTE2440 Hello.

修改同目录下的“Makefile”文件,在合适的行添加如下内容:

#

# Makefile for the kernel character device drivers.

 

#

#

# This file contains the font map for the default (hardware) font

#

obj-$(CONFIG_ CCTE_HELLO) += hello.o

 

配置内核

然后输入:#make menuconfig,然后配置如下:

Device Drivers --->

Character devices --->

<*> CCTE2440 Hello Driver

将其选择为“M”(模块),然后保存配置,编译出内核镜像烧写到开发板中。或是下载到开发板上运行。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值