Linux 设备驱动程序进阶(0)

很久没有写技术博文了,从这里开始我的研究生生涯,转眼就要在职场上养家糊口,生活真的不容易,幸好还有技术相伴为伍。

 

由于工作的关系,终于接触到linux网络和kernel的编程,总体来说总是一个好的契机。让我能够深入操作系统内核。做过一段时间的用户程序的开发,总是在Windows平台上,终于有机会在linux上做点东西,还是很兴奋的。

 

首先是一个Hello World的内核程序,然后就是一大堆编译的问题,由于没有接触过Linux所以花费了很多时间在这上面。

 

1) hellokernel.c 我的编译环境是在虚拟的Linux Redhat 5.0 上编译的

 

#include <linux/init.h>

#include <linux/module.h>

 

MODULE_LICENSE("Dual BSD/GPL"); //这个宏的意思我还是不太明白,直接抄了过来

static int hello_init(void)

{

    printk(KERN_ALERT"Hello,world/n");

    return 0;

}

 

static void hello_exit(void)

{

    printk(KERN_ALERT"Goodby,cruel world/n");

}

 

module_init(hello_init);  //当内核模块被装载的时候调用hello_init函数

module_exit(hello_exit); //当内核模块被卸载的时候调用hello_exit函数

 

2)源代码准备好了之后下面就是编译的问题

 

step1:  准备好linux内核源代码,注意版本号要与主机一致,这里因为我直接在主机(Linux机器)上编译,所以不存在交叉编译的问题。查看linux机器的内核版本号有很多命令,我用的是uname -r

[root@localhost ~]# uname -r
2.6.18-128.el5

看到内核版本之后就可以在官网上下载对应版本的内核。http://www.kernel.org/pub/linux/kernel/v2.6/在这里找到linux-2.6.18.tar.bz2 这个版本,然后解压到/usr/src/目录下。解压命令是tar -xvf linux-2.6.18.tar.bz2就可以了。

step2:  准备工作做好之后首先是编译内核,如果你下载的内核版本和你的主机版本是一一对应的,那么编译起来很简单的,一般没有什么问题的,主要就是几个make命令:

make oldconfig

make prepare

make scripts

step 3: 下面就是在hellokernel.c的目录下编写Makefile文件,注意Makefile的第一字母必须大写,我就是在这里犯错,查了半天没查出问题。Makefile的编写对于这个例子很简单,但是如果复杂的内核模块的开发还是要好好学习怎么编写的。

 

其实就是简单的几句话就ok了:

 

obj-m := hellokernel.o //目标模块的编译来自于hellokernel.o的文件, hellokernel.o的文件来自于你的hell

KERNELDIR := /usr/src/linux-2.6.18/ //把这个宏设为刚在内核源代码解压的那个目录

 

default:

            make -C $(KERNELDIR) M=$(shell pwd) modules  //这句话是说从内核源代码目录查找hellokernel.c需要的文件,并且在当前目录下生成编译之后的模块

step 4: 然后就是键入make命令

 

[root@localhost ~]# make
make -C /usr/src/linux-2.6.18/ M=/root modules
make[1]: Entering directory `/usr/src/linux-2.6.18'
  Building modules, stage 2.
  MODPOST
  LD [M]  /root/hellokernel.ko
make[1]: Leaving directory `/usr/src/linux-2.6.18'
这样就编译完成,这时你会发现在当前目录下多出许多文件,有*.o,*.mod.o等,这里我们可以在makefile里面加一行rm -f 的命令就可以了,去做一些清理工作。

 

3)加载内核模块,这里就可以加载内核模块了,一般是用insmod hellokernel.ko这条命令,这里顺便提一句我在编译内核模块的时候开始的时候遇到一个Warning:

 

 WARNING: Symbol version dump /usr/src/linux-2.6.18/Module.symvers
           is missing; modules will have no dependencies and modversions.

这是缺少Module.symvers文件的原因,其实解决这个问题很简单,因为在/usr/src/kernels目录下有一个同样的文件。直接拷贝过去就可以了。

 

[root@localhost src]# cp ./kernels/2.6.18-128.el5-i686/Module.symvers /usr/src/linux-2.6.18/ 这样再次编译Warning就没有了。

 

加载了模块之后我们可以用lsmod | grep hellokernel查看是否被加载。并且可以查看/var/log/messages是否打印出来信息。

[root@localhost src]# tail -F /var/log/messages
Mar 17 23:02:31 localhost kernel: Hello, world
Mar 17 23:03:19 localhost kernel: Goodby, cruel world
Mar 17 23:05:10 localhost kernel: Hello, world
Mar 17 23:05:19 localhost kernel: Goodby, cruel world
Mar 18 01:24:36 localhost kernel: Hello, world
Mar 18 01:32:47 localhost kernel: Goodby, cruel world
Mar 18 01:34:51 localhost kernel: Hello, world
Mar 18 01:35:04 localhost kernel: Goodby, cruel world
Mar 18 18:07:34 localhost kernel: Hello, world
卸载模块的命令是rmmod hellokernel 从上面的信息也可以看出Goodby,cruel world确实卸载了模块。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值