树莓派4驱动开发入门
遇到的问题
驱动insmod错误
在电脑虚拟机下交叉编译树莓派4的内核模块,出现了以下错误。
pi@raspberrypi:~ $ sudo insmod hello.ko
insmod: ERROR: could not insert module hello.ko: Invalid module format
检查虚拟机端的内核源码版本和树莓派的内核版本
错误可能是由于内核版本不一致造成的,所以先查看内核版本是否对应
查看树莓派的内核
树莓派的内核版本为4.19.97-v7l+
pi@raspberrypi:~ $ uname -a
Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux
查看下载到虚拟机的内核源码版本
4.19.127和4.19.97相差了挺多,估计是这个原因导致insmod失败。(因为内核源码git老是失败,我的内核源码是我同学发给我的,我同学的内核源码同样是4.19.127,他的树莓派内核是4.19.118的,但是他的能insmod成功)不管怎样,还是把树莓派的内核更换成4.19.127。
heshishun@ubuntu:~/Rpi_linux$ make kernelrelease
4.19.127-v7l+
虚拟机编译内核源码过程
内核源码获取
内核源码是同学git下来发送给我的,不嫌麻烦可以git。
Rpi_linux.tar.gz解压后,得到的是我同学已经编译过了文件(他的是树莓派3B)。
Desktop driver Music Rpi_linux Videos
Documents examples.desktop Pictures Rpi_linux.tar.gz
Downloads heshishun Public Templates
执行过编译操作的内核源码做重新编译需要进行清理操作
heshishun@ubuntu:~/Rpi_linux$ make clean
CLEAN .
CLEAN certs
CLEAN drivers/scsi
CLEAN drivers/tty/vt
CLEAN drivers/video/logo
CLEAN kernel/debug/kdb
CLEAN kernel
CLEAN lib/raid6
CLEAN lib
CLEAN net/wireless
CLEAN usr
CLEAN .tmp_versions
heshishun@ubuntu:~/Rpi_linux$ make mrproper
CLEAN scripts/basic
CLEAN scripts/dtc
CLEAN scripts/genksyms
CLEAN scripts/kconfig
CLEAN scripts/mod
CLEAN scripts
CLEAN include/config include/generated arch/arm/include/generated
CLEAN .config .config.old .version Module.symvers
heshishun@ubuntu:~/Rpi_linux$ make distclean
CLEAN scripts/basic
CLEAN scripts/kconfig
清理之后得到了干净的内核源码
heshishun@ubuntu:~/Rpi_linux$ ls
arch COPYING drivers init kernel Makefile samples tools
block CREDITS firmware ipc lib mm scripts usr
certs crypto fs Kbuild LICENSES net security virt
Documentation include Kconfig MAINTAINERS README sound
交叉编译工具链
获取文件,这个不涉及版本,我也git不下来,也是别人分享给我的。文件解压后目录中存在几个文件夹,本例使用gcc-linaro-arm-linux-gnueabihf-raspbian 或 gcc-linaro-arm-linux-gnueabihf-raspbian-x64。前者对应32位系统后者对应64位系统。
arm-bcm2708hardfp-linux-gnueabi
gcc-linaro-arm-linux-gnueabihf-raspbian
arm-bcm2708-linux-gnueabi
gcc-linaro-arm-linux-gnueabihf-raspbian-x64
raspberrypi-tools.tar.bz2
heshishun@ubuntu:/opt/tools/arm-bcm2708$ ls
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
加入环境变量,在/.bashrc文件中加入gcc交叉工具链目录。
heshishun@ubuntu:/opt/tools/arm-bcm2708$ sudo gedit ~/.bashrc
再打开的文档最后添加路径(根据文件所在的目录,我的目录是这样)
export PATH=$PATH:/opt/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin
测试是否安装成功
heshishun@ubuntu:/opt/tools/arm-bcm2708$ arm-linux-gnueabihf-gcc -v
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/opt/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../libexec/gcc/arm-linux-gnueabihf/4.8.3/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: /cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/src/gcc-linaro-4.8-2014.01/configure --build=i686-build_pc-linux-gnu --host=i686-build_pc-linux-gnu --target=arm-linux-gnueabihf --prefix=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/install --with-sysroot=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/install/arm-linux-gnueabihf/libc --enable-languages=c,c++,fortran --disable-multilib --enable-multiarch --with-arch=armv6 --with-tune=arm1176jz-s --with-fpu=vfp --with-float=hard --with-pkgversion='crosstool-NG linaro-1.13.1-4.8-2014.01 - Linaro GCC 2013.11' --with-bugurl=https://bugs.launchpad.net/gcc-linaro --enable-__cxa_atexit --enable-libmudflap --enable-libgomp --enable-libssp --with-gmp=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-mpfr=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-mpc=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-isl=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-cloog=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-libelf=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --enable-threads=posix --disable-libstdcxx-pch --enable-linker-build-id --enable-plugin --enable-gold --with-local-prefix=/cbuild/slaves/oorts/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/install/arm-linux-gnueabihf/libc --enable-c99 --enable-long-long --with-float=hard
Thread model: posix
gcc version 4.8.3 20140106 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2014.01 - Linaro GCC 2013.11)
编译步骤
首先配置内核,在内核源码目录下运行命令
heshishun@ubuntu:~/Rpi_linux$ KERNEL=kernel7l
heshishun@ubuntu:~/Rpi_linux$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2711_defconfig
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
YACC scripts/kconfig/zconf.tab.c
LEX scripts/kconfig/zconf.lex.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
#
# configuration written to .config
#
然后编译
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dts
主要编译三个东西zImage,modules,dts。
zImage就是要替换的树莓派镜像文件。
编译时间需要很久,我的电脑要编译一小时左右。
更换树莓派内核
主要是将编译出来的文件转移到SD卡相应的位置
参考链接
https://blog.csdn.net/sjt19910311/article/details/104335457
最后在树莓派中的/boot目录下
pi@raspberrypi:/boot $ sudo vim config.txt
在config.txt最后指定内核
kernel=kernel7l.img
不要选错了噢
重启后查看内核
pi@raspberrypi:/boot $ uname -a
Linux raspberrypi 4.19.127-v7l+ #1 SMP Tue Jul 28 04:28:33 PDT 2020 armv7l GNU/Linux
内核更新完成
测试insmod
pi@raspberrypi:~ $ sudo insmod hello.ko
pi@raspberrypi:~ $ sudo rmmod hello
pi@raspberrypi:~ $ dmesg
查看日志
于是驱动开发就开始了.