环境
PC:
Ubuntu 18.04 64位
树莓派:
Linux raspberrypi 4.4.21-v7+ #911 SMP Thu Sep 15 14:22:38 BST 2016 armv7l GNU/Linux
搭建交叉编译链
搭建交叉编译链可以在PC上编译raspberry pi 的程序
安装步骤
新建文件夹并下载交叉编译工具
mkdir raspberry_pi
cd raspberry_pi
git clone git://github.com/raspberrypi/tools.git
cd tools/arm-bcm2708/
这时已经下载好了 ls查看一下有6个工具
arm-bcm2708hardfp-linux-gnueabi
arm-rpi-4.9.3-linux-gnueabihf
arm-bcm2708-linux-gnueabi
gcc-linaro-arm-linux-gnueabihf-raspbian
arm-linux-gnueabihf
gcc-linaro-arm-linux-gnueabihf-raspbian-x64
在这里我们使用的是 gcc-linaro-arm-linux-gnueabihf-raspbian-x64 版本
接下来就是把交叉编译工具加入环境变量
sudo nano~/.bashrc
然后最后加上
export PATH=$PATH:/raspberry_pi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
export PATH=$PATH:/raspberry_pi/tools/arm-bcm2708-linux-gnueabi/bin
在控制台输入
source ~/.bashrc
试一下是否成功
arm-linux-gnueabihf-gcc -v
helloworld程序测试
在/raspberry_pi目录下新建hello
mkdir hello
然后添加以下两个文件
hello.c
#include <stdio.h>
int main(void)
{
printf(“Hello World\n”);
}
Makefile
CC=arm-linux-gnueabihf-gcc
hello:hello.o
clean:
rm -rf hello.o hello
执行
sudo make
他会提示没有安装arm-linux-gnueabihf-gcc
这是因为sudo的环境和当前的环境不一样导致的
有两种解决办法
第一种
先打开一个超级用户权限的shell:
sudo –s
在当前shell下,设置环境变量:
export PATH=$PATH:/raspberry_pi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
在sudo make
第二种
控制台输入
sudo su -p
然后再make
这时候会生成hello文件
把这个hello文件拷贝到树莓派上
再
chmod 777 hello
./hello
就能够看到输出hello world了
这样子第一部分就完成了
编译内核
获取内核源码并编译
要编译驱动得有交叉编译的工具还有编译好的内核,不然内核的版本就对不上了。
先获取内核的源码在进行编译
先对树莓派进行
uname -a
发现是4.4.12
于是我就在GitHub上下载了一份树莓派4.4的源码
https://github.com/raspberrypi/linux/tree/rpi-4.4.y
下载下来并解压到我的/work目录
然后
cd /work/linux-rpi-4.4.y
KERNEL=kernel7
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig
然后再
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs
等好了之后这样的内核就编译完成了
本想以为大功告成了就去试了一下,写了一个helloworld
在work目录下创建一个文件夹
mkdir hello
hello.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.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"Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
Makefile
ifneq ( ( K E R N E L R E L E A S E ) , ) o b j − m : = h e l l o . o e l s e P W D : = (KERNELRELEASE),) obj-m := hello.o else PWD := (KERNELRELEASE),)obj−m:=hello.oelsePWD:=(shell pwd)
KDIR := /work/linux-rpi-4.4.y
all:
make -C ( K D I R ) M = (KDIR) M= (KDIR)M=(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
clean:
rm -f *.ko *.o *.mod.o *.mod.c .symvers modul
endif
然后就make一下
也编译成功了所以就把hello.ko拷贝到树莓派上
在hello.ko所在目录
sudo insmod hello.ko
结果就报错了
insmod: ERROR: could not insert module hello.ko: Invalid module format
然后再输入
cat /var/log/syslog
在最后一行可以看到
raspberrypi kernel: [ 1610.696884] hello: disagrees about version of symbol module_layout
查了一下意思就是版本不对,后来想想我下载的是4.4,系统是4.4.12,可能后面的对不上。所以就多了一步,把编译好的内核弄到树莓派上
更换树莓派内核
先把树莓派的SD卡取出来,放到Ubuntu里面,我是用的是Raspbian系统的。插入后在终端输入
lsblk
回显
sdb
–sdb1
–sdb2
sdb1作为FAT(启动)分区,和sdb2作为文件系统的ext4(根)分区。
然后就是要拷贝到内存卡上了
mkdir /mnt
mkdir /mnt/fat32
mkdir /mnt/ext4
sudo mount /dev/sdb1 /mnt/fat32
sudo mount /dev/sdb2 /mnt/ext4
然后就是安装模块
sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=mnt/ext4 modules_install
最后,将内核复制到SD卡上,确保备份旧内核:
sudo cp /mnt/fat32/ K E R N E L . i m g m n t / f a t 32 / KERNEL.img mnt/fat32/ KERNEL.imgmnt/fat32/KERNEL-backup.img
sudo cp /work/linux-rpi-4.4.y/arch/arm/boot/zImage /mnt/fat32/$KERNEL.img
sudo cp /work/linux-rpi-4.4.y/arch/arm/boot/dts/.dtb /mnt/fat32/
sudo cp /work/linux-rpi-4.4.y/arch/arm/boot/dts/overlays/.dtb* /mnt/fat32/overlays/
sudo cp /work/linux-rpi-4.4.y/arch/arm/boot/dts/overlays/README /mnt/fat32/overlays/
sudo umount /mnt/fat32
sudo umount /mnt/ext4
另一个选择是将内核复制到同一个地方,但使用不同的文件名 - 例如kernel-myconfig.img - 而不是覆盖kernel.img文件。然后,您可以编辑config.txt文件以选择Pi将引导到的内核:
kernel=kernel-myconfig.img
最后就插入Pi,启动
安装驱动
由于上一步已经编译好了驱动所以就直接拿来用
直接
sudo insmod hello.ko
没有报错,那就是可以了
确保安装了再
lsmod
可以清楚的看到hello
最后
cat /var/log/syslog
可以看到
raspberrypi kernel: [ 502.264231] Hello, world
如果再
sudo rmmod hello
cat /var/lod/syslog
则会显示
raspberrypi kernel: [ 491.700475] Goodbye, cruel world
到这里,驱动开发的环境就已经配置好了