前言
笔者想用树莓派5做运动控制器,但是原生linux的实时性比较差,为了达到硬实时,需要移植rt-patch
树莓派5官方内核编译
1、下载官方代码,笔者使用的是"rpi-6.1.y"这个branch
git clone https://github.com/raspberrypi/linux.git
2、编译内核
chad_compile.sh
#! /bin/bash
# https://www.raspberrypi.com/documentation/computers/linux_kernel.html#cross-compiling-the-kernel
KERNEL=kernel_2712
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2712_defconfig
# make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- chad_rt_defconfig #打上rt-patch之后用这个配置
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbs -j8
3、安装到SD卡
chad_install.sh
#! /bin/bash
# bootfs: mnt/fat32 -> /media/rlk/bootfs
# rootfs: mnt/ext4 -> /media/rlk/rootfs
KERNEL=kernel_2712
sudo env PATH=$PATH make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=/media/rlk/rootfs modules_install
sudo cp /media/rlk/bootfs/$KERNEL.img /media/rlk/bootfs/$KERNEL-backup.img #backup old kernel
sudo cp arch/arm64/boot/Image /media/rlk/bootfs/$KERNEL.img # copy new kernel
sudo cp arch/arm64/boot/dts/broadcom/*.dtb /media/rlk/bootfs/
sudo cp arch/arm64/boot/dts/overlays/*.dtb* /media/rlk/bootfs/overlays/
sudo cp arch/arm64/boot/dts/overlays/README /media/rlk/bootfs/overlays/
sync
打rt-patch
1、下载对应版本的patch
去https://www.kernel.org/pub/linux/kernel/projects/rt/
网站下载指定版本对应的patch,本文对应的是patch-6.1.80-rt26.patch.gz
,在编译服务器上解压
2、在Linux源码目录内,运行patch -p1 < patch-6.1.80-rt26.patch
,apply的过程没有报错
3、在menuconfig中打开CONFIG_PREEMPT_RT
选项
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
位置在
Location:
-> General setup
-> Preemption Model (<choice> [=y])
-> Fully Preemptible Kernel (Real-Time) (PREEMPT_RT [=y])
配置界面是这样的,一定要使能最后一个
( ) No Forced Preemption (Server)
( ) Voluntary Kernel Preemption (Desktop)
( ) Preemptible Kernel (Low-Latency Desktop)
(X) Fully Preemptible Kernel (Real-Time)
5、保存配置
(1)配置之后打开.config
看下CONFIG_PREEMPT_RT
是不是已经置为y
cat .config | grep "CONFIG_PREEMPT_RT=y"
(2)保存配置,生成config最小子集->defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- savedefconfig
(3)将配置保存在arch/arm64/configs/
中
cp defconfig arch/arm64/configs/chad_rt_defconfig
(4)下次编译的时候,把编译脚本中改成
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- chad_rt_defconfig
6、编译内核,烧到sd卡中,启动树莓派
有如下打印说明rt-patch已经成功打上了
root@chad-pi:/sys/kernel/debug/tracing# uname -a
Linux chad-pi 6.1.77-rt26-v8-16k #10 SMP PREEMPT_RT Sun Mar 3 15:52:21 CST 2024 aarch64 GNU/Linux
遇到的问题
1、树莓派驱动加载不上
报错:uio: disagrees about version of symbol module_layout
(1)检查vermagic
root@chad-pi:/# modinfo /lib/modules/6.1.77-rt26-v8-16k/kernel/drivers/char/raspberrypi-gpiomem.ko
filename: /lib/modules/6.1.77-rt26-v8-16k/kernel/drivers/char/raspberrypi-gpiomem.ko
author: Jonathan Bell <jonathan@raspberrypi.com>
description: Driver for accessing GPIOs from userspace
license: Dual BSD/GPL
alias: platform:rpi-gpiomem
srcversion: 7DB7557F324874FAE92BAB5
alias: of:N*T*Craspberrypi,gpiomemC*
alias: of:N*T*Craspberrypi,gpiomem
alias: of:N*T*Cbrcm,bcm2835-gpiomemC*
alias: of:N*T*Cbrcm,bcm2835-gpiomem
depends:
intree: Y
name: raspberrypi_gpiomem
vermagic: 6.1.77-rt26-v8-16k SMP preempt mod_unload modversions aarch64
root@chad-pi:/# uname -r
6.1.77-rt26-v8-16k
chad@chad-pi:~$ uname -a
Linux chad-pi 6.1.77-rt26-v8-16k #7 SMP PREEMPT_RT Sun Mar 3 13:53:47 CST 2024 aarch64 GNU/Linux
有问题: vermagic中preempt应该是preempt_rt,说明用户态这个ko版本不对
(2)检查module_layout
root@chad-pi:/# modprobe --dump-modversions /lib/modules/6.1.77-rt26-v8-16k/kernel/drivers/char/raspberrypi-gpiomem.ko
0x6a7bf841 __platform_driver_register
0x5582ab2b device_destroy
0x099877a9 class_destroy
0x41003dd1 cdev_del
0x6091b333 unregister_chrdev_region
0x037a0cba kfree
0xe4952537 _dev_info
0x868e7b97 phys_mem_access_prot
0x7b81abce remap_pfn_range
0x0e91b360 kmalloc_caches
0x9660e6d2 kmalloc_trace
0x0e7e76f8 of_match_device
0x4feb5425 of_property_read_string
0x08ea0146 platform_get_resource
0xe3ec2f2b alloc_chrdev_region
0xee2d4b14 cdev_init
0x946c5bc3 cdev_add
0xb71da655 __class_create
0x4eaf040c device_create
0xe4b9fb09 _dev_err
0xf0825678 platform_driver_unregister
0xfd75da04 generic_access_phys
0x9f3b8783 module_layout
root@chad-pi:/# cat /usr/src/linux-headers-6.1.0-rpi7-rpi-2712/Module.symvers | grep module_layout
0xf7038a43 module_layout vmlinux EXPORT_SYMBOL
两个module_layout不一样,也能确认是install的问题
在check_version直接return 1
报错:uio: version magic ‘6.1.77-rt26-v8-16k SMP preempt mod_unload modversions aarch64’ should be ‘6.1.77-rt26-v8-16k SMP preempt_rt mod_unload modversions aarch64’
看来就是差在这个rt上了!果然是rt-patch引入的问题
在服务器上看编译出来的ko是vermagic: 6.1.77-rt26-v8-16k SMP preempt_rt mod_unload modversions aarch64
,这就说明是往机器里面烧的过程出问题了
破案了:是因为在/media/rlk/下被我建了一个rootfs,应该是之前install但是没有插sd卡导致的,这导致sd卡被挂载到rootfs1中,脚本中写的是rootfs,所以moudle_install就没有成功