由于本人在该过程中踩了很多坑,而且找到的相关文章都比较旧,于是写一篇经验贴。
大坑:
后来才刷到这个,# preempt_rt patched ARM64 kernel will not start on raspberry pi zero w2
大概就是说64位系统 的zero-2w在安装preempt-rt补丁后,核心会挂起导致无法启动。 他说的情况和我的十分符合,因为我的zero-2w一开始是64位系统,在尝试打完补丁、更换核心后,出现了树莓派无法连接wifi,系统日志也没有消息等情况(这里可能自己没找到具体错误,因为我连接显示屏也无显示),多次尝试都是如此。
于是我选择去树莓派官网重装了系统,选择了推荐的32位系统
我选择的是在笔记本的虚拟机Ubuntu22.04中进行交叉编译,因为之前曾经在zero-2w中多次尝试过直接编译,但都会进入类似死锁的状态,无响应(这也可能是64位系统的内存不足的问题,换成32位后我没有尝试过直接编译)
具体步骤:
首先在你的虚拟机/其他Linux系统中的一个工作目录中创建一个工作文件夹rpi-kernel,然后进入该文件夹创建一个新核心目录rt-kernel
然后下载树莓派官方源码
因为树莓派的系统是6.1.21-v7+,所以我用的是rpi-6.1.y这个分支的源码 将该源码解压到工作文件夹(rpi-kernel)中,并将文件夹重命名为linux(不改的话也行,后续操作对应修改就是)
下一步是下载rt补丁文件
其中找到一个比rpi-6.1.y源码版本要旧的版本,如我当前下载的源码是6.1.74,就选一个6.1.74之前的补丁版本。我下载的是6.1.46-rt13.patch. 将其解压到工作目录(rpi-kernel)中
然后进入源码目录中打开终端
shell
sudo patch -p1 < ~/workspace/pi/rpi-new-kernel/patch-6.1-rc7-rt5.patch
将里面的文件目录改成你解压好的补丁目录即可 这里可能会遇到一个
shell
file to patch:
个人估计是因为源码版本不完全契合导致有些文件是没有的,直接回车跳过即可
下一步开始进行交叉编译: 下载必要的工具链:
shell
sudo apt install git bc bison flex libssl-dev make libc6-dev libncurses5-dev
sudo apt install crossbuild-essential-armhf
然后设置变量(export语句效果是只在当前终端起效,关闭该终端后需要重新键入),这一步很重要!
shell
export ARCH=arm
export INSTALL_MOD_PATH=~/rpi-kernel/rt-kernel #目录修改为你的对应目录
export INSTALL_DTBS_PATH=~/rpi-kernel/rt-kernel #目录修改为你的对应目录
export CROSS_COMPILE=arm-linux-gnueabihf- CFLAGS="-march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16"
export KERNEL=kernel7
然后生成一个默认配置
shell
make bcm2709_defconfig
然后进入该配置进行设置:
shell
make menuconfig
如无报错则进入该界面:
进入general setup中 确认timers subsystem的High Resolution Timer Support选项已选
然后将Preemption Model设置为Fully Preemptible Kernel (Real-Time),如果没有这一选项说明源码打补丁这一步出了问题。
返回最初界面进入kernel features中,将timer frequency改为1000Hz
然后保存退出。
然后继续在该终端进行以下操作(此时应该在linux目录下)
shell
make -j4 zImage
make -j4 modules
make -j4 dtbs
make -j4 modules_install
make -j4 dtbs_install
接着在你的rt-kernel文件夹下创建一个boot目录
shell
mkdir $INSTALL_MOD_PATH/boot
然后
shell
./scripts/mkknlimg ./arch/arm/boot/zImage $INSTALL_MOD_PATH/boot/$KERNEL_rt.img
这是一个旧教程的一步,由于新的源码没有该脚本,所以需要自己搞一个mkknlimg脚本文件
将其下载到linux/scripts目录下即可
完成上述操作后,进入你的新内核目录(rt-kernel)里面,打包
shell
tar czf ../rt-kernel.tgz *
生成的打包文件在这
将其传输到你的树莓派的/tmp目录中,然后进行以下操作(此时开始在树莓派中操作)
shell
~$ cd /tmp
/tmp$ tar xzf rt-kernel.tgz
/tmp$ cd boot
/tmp/boot$ sudo cp -rd * /boot/
/tmp/boot$ cd ../lib
/tmp/lib$ sudo cp -dr * /lib/
/tmp/lib$ cd ../overlays
/tmp/overlays$ sudo cp -d * /boot/overlays
/tmp/overlays$ cd ..
/tmp$ sudo cp -d bcm* /boot/
然后进入/boot文件夹,修改config.txt文件
shell
sudo nano config.txt
在[all]的下方加入
kernel=kernel7_rt.img
即你生成在rt-kernel/boot中的文件名 重启树莓派 输入
shell
uname -a
看到有 preempt-rt,则成功
参考资料:
lemariva.com/blog/2018/0...
techexplorations.com/raspberry-p...