树莓派内核编译及编写驱动

树莓派Git库这里下载树莓派的内核源码linux 、编译工具tools和fireware固件。
将源码解压,查看一下最外层的Makefile,里面有几个字段需要注意 ARCH CROSS_COMPILE

ARCH表示要编译的平台架构,在/arch目录下存放了硬件平台的内容,每一个平台占用一个目录,由于在树莓派下,所以ARCH=arm

CROSS_COMPILE表示用到的编译器的前缀,在下载的编译工具下有4种编译工具,选择其中的一个,比如~/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- 。这个路径比较长,可以定义一个变量 export CCPREFIX=~/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-

1.开始编译内核

​ make需要用到包含一系列配置信息的.config文件,该文件可以用make config命令生成。一般从正在运行的树莓 派上/proc/config.gz解压出config文件,改名为.config。

make ARCH=arm CROSS_COMPILE=$CCPREFIX -jn+1

-j(n+1) 表示多核处理器下用n个核来编译,越多越快。

make ARCH=arm CROSS_COMPILE=$CCPREFIX bzImage

生成zImage Image vmlinux 经测试都能引导启动。也可以用tools下的imagemake工具把上面的镜像解压成kernel.img。

make bzImage段在相应的平台目录下的Makefile,已经不在支持zImage命令

生成的zImage为压缩的内核,Image为非压缩的内核

make ARCH=arm CROSS_COMPILE=$CCPREFIX modules

生成模块,若出现错误重新配置.config,关掉出错的模块。

make ARCH=arm CROSS_COMPILE=$CCPREFIX modules_install INSTALL_MOD_PATH=(modules path)

将模块安装到 INSTALL_MOD_PATH 下,若没有指定,将会默认安装到/lib目录下,如图

在INSTALL_MOD_PATH下会生成/lib/modules和/lib/fireware

至此,内核编译完成。将内核镜像放到 /boot 下,将/lib/modules和/lib/fireware放到/lib下。也可以再将fireware固件下的/boot/bootcode.bin /boot/fixup.dat /boot/start.elf 放到/boot下,把/opt下的vc 替换 /opt的vc(判断是硬浮点还是软浮点)

2.自定义驱动模块编译

hello world驱动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// hello.c
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");

static int hello_init(void)
{
printk(KERN_ALERT "hello world!\n");
return 0;
}

static void hello_exit(void)
{
printk(KERN_ALERT "goodbye!\n");
}

module_init(hello_init);
module_exit(hello_exit);

Makefile文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# example of driver module on arm

ifneq ($(KERNELRELEASE),)
obj-m := hello.o
else
KDIR := ~/linux-rpi-3.12.y/
PWD = $(shell pwd)
CCPREFIX=~/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-

all:
make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=$(CCPREFIX)

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

endif

make进行编译,编译成功后用 file 命令检查hello.ko的属性是否为arm类型。 模块加载成功会在dmesg下显示。

KDIR也可以为~/linux-rpi-3.12.y/INSTALL_MOD_PATH/lib/modules/3.12.36/build,实际上这和~/linux-rpi-3.12.y/是一样的,因为~/linux-rpi-3.12.y/INSTALL_MOD_PATH/lib/modules/3.12.36/build是一个软连接,又链接到~/linux-rpi-3.12.y/。这只是在有源码的时候才用的路径。如果在电脑上编译本机驱动时,因为没有源码包,而/usr/src下面的源码存在,这时软连接会链接到这里。

虽然很不要脸,但是还请您多多打赏 ^_^