树莓派内核模块开发HelloWord

有时候为了方便与硬件更好交互,可能会需要为它专门写个驱动。这就涉及到了内核模块的开发。
其实内核模块的开发没有想象的那么复杂,也就是准备工作有点繁琐,开源的东西都这样,一切都得自己来。

安装kernel header源码
首先查看当前使用的内核版本

$ uname -r
3.6.11+

我的系统是2013-02-09-wheezy-raspbian,所以显示出来的内核版本是3.6.11+
首先看看apt源里面有没有,有的话直接安装

$ apt-cache search linux-headers

没有找到3.6.11+相关的,其中的3.6的一些down下来也没法用。
下面就手动把3.6.11+的header-src搞下来。
下载3.6.11+的内核源码

$ wget https://github.com/raspberrypi/linux/archive/rpi-3.6.y.tar.gz
解压
$ tar xvfz rpi-3.6.y.tar.gz
取得root权限
$ su
将源码移至/usr/src目录
# mv linux-rpi-3.6.y /usr/src
建立内核模块库目录的链接
# ln -s /usr/src/linux-rpi-3.6.y /lib/modules/3.6.11+/build
# cd /lib/modules/3.6.11+/build
make mrproper可以看作更加强劲的make clean命令,用来清除环境变量,即清除配置文件,一般编译内核前都要运行
# make mrproper
将当前正在使用的系统的内核配置生成内核配置信息
# gzip -dc /proc/config.gz > .config
生成编译内核所需要的东西
# make modules_prepare
获取内核编译时生成的内核模块导出符号文件,因为不是从头编译内核,所以没有,但是编译内核模块需要这个
# wget https://github.com/raspberrypi/firmware/raw/master/extra/Module.symvers
退出root
# exit

编写hello world 内核模块
写一个最简单的内核模块 hello.c, 这个内核只会在加载的时候输出 helo,word,移除时输出goodbye
在树梅派上找个地方新建一个目录,创建文件hello.c:

#include <linux init.h="">
#include <linux module.h="">
MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void) {
printk(KERN_ALERT "Hello, world");
return 0;
}

static void hello_exit(void) {
printk(KERN_ALERT "Goodbye, cruel world");
}

module_init(hello_init);
module_exit(hello_exit);

创建Makefile文件:

ifneq ($(KERNELRELEASE),)

obj-m := hello.o

else
	
KDIR := /home/hcx/work/boards/RPi/kernel/linux-rpi-3.6.y
all:
	make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=/home/hcx/work/boards/RPi/kernel/RpiTools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-

clean:
	rm -f *.ko *.o *.mod.o *.mod.c *.symvers  modul*

endif

准备工作做好了,现在开始编译

$ make

会生成以下文件:

$ ls
hello.c   hello.mod.c  hello.o   modules.order
hello.ko  hello.mod.o  Makefile  Module.symvers

查看这个内核模块的信息:

$ modinfo hello.ko
filename:       /home/pi/sensors/kernel-model/hello.ko
license:        Dual BSD/GPL
srcversion:     9AE281A251509460F68E55F
depends:        
vermagic:       3.6.11 preempt mod_unload modversions ARMv6

加载内核:

$ sudo sudo insmod hello.ko

命令行没有输出,别急,继续移除它:

$ sudo rmmod hello

现在查看输出:

$ dmesg | tail -5
[ 7175.039569] Hello, world
[ 7199.989110] Goodbye, cruel world

可以看到,这个hello内核模块工作的很正常。

这是一篇发布于 10年 前的文章,其中的信息可能已经有所发展或是发生改变,请了解。


1 Trackback / Pingback

  1. 字符设备驱动(mknod框架) | openRPi - 博客

评论已关闭。