手动编译 Rockchip BSP 内核以支持 Mainline 不支持的功能,本文以 RK3566 为例对内核进行重新编译。
Intro
这里先介绍一个概念,BSP。
BSP(Board Support Package),即“Rockchip 官方维护的 Linux 内核”;与之相对的是Mainline Kernel(主线内核),即 Linux 官方内核(kernel.org),驱动由 Linux 社区维护。
BSP本质上是芯片厂商为了让硬件尽快能投入市场使用,自己维护的一套 Linux 内核修订;目标是整板能够先跑起来。例如Rockchip芯片中的VPU、NPU、GPU等等都由Rockchip自行开发或修改,只要AOSP(Android)能用、Linux 能用,他们就完成任务了。这些在代码层面上很多是不符合Linux风格也不易于Linux社区维护的,因此由厂商自行维护,没有合入主线。
至于其他厂商,诸如 Intel 的策略就是在硬件发布之前,就把驱动提交到 Linux 主线,等其CPU上市时 Linux 主线可能已经把相关代码合入主线了。另外还有比如 nvidia 的开发板 Jetson,也是自己有维护一套BSP内核。
硬件
仍然是 Panther X2,RK3566,4GB内存,无EMMC存储(拆掉了),64G闪迪金卡。
系统是Armbian Linux v26.02.0 for RK.Panther-X2,原来内核版本是6.12-ophub后面忘了。
编译机
为了确保编译稳定和资源获取方便,本文环境均在阿里云-日本-东京三区ECS完成,16核心,16G内存,50G ESSD,100Mbps CDT,ubuntu 24.04。
目标
能够引出/dev/mpp_service。
内核编译
1. 安装依赖
1 | apt update |
2. 下载源码
本文采用了第三方的内核源码(ArmSoM),最早是考虑到该厂商有差不多的board因此采用。
后使用官方仓库rockchip-linux/kernel: BSP kernel source根据本文步骤也可以正常编译。
- 下载BSP内核源码我这里编译了6.1版本的内核,主要考虑到本身在使用Debian 12。相关的BSP内核版本还有5.10和4.9等,例如我另外一块Orange Pi 3b(3566)就是5.10的内核,不过底层也是Debian 12。
1
2mkdir ~/src && cd ~/src
git clone --depth=1 --branch develop-6.1 https://github.com/rockchip-linux/kernel.git linux-bsp61 - 下载armbian ophub这个仓库所使用的内核源码用于提取文件
1
2cd ~/src
git clone --depth=1 https://github.com/unifreq/linux-6.1.y.git linux-mainline61
3. 准备Panther X2的板级支持
- 复制设备树
1
2
3cd ~/src/linux-bsp61
cp ../linux-mainline61/arch/arm64/boot/dts/rockchip/rk3566-panther-x2.dts \
arch/arm64/boot/dts/rockchip/ - 编辑Makefile使得编译时支持Panther X2添加:
1
nano arch/arm64/boot/dts/rockchip/Makefile
到上述文件末尾1
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-panther-x2.dtb
4. 编译
- 编译配置
1
2
3
4
5
6
7
8
9
10cd ~/src/linux-bsp61
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
export OUT=$PWD/out
make O="$OUT" \
ARCH=arm64 \
CROSS_COMPILE=aarch64-linux-gnu- \
rockchip_linux_defconfig - 设置版本号,随便写点什么和mainline区分开就行应用
1
2
3scripts/config \
--file "$OUT/.config" \
--set-str CONFIG_LOCALVERSION "-panther-bsp61"1
2
3
4make O="$OUT" \
ARCH=arm64 \
CROSS_COMPILE=aarch64-linux-gnu- \
olddefconfig - 确认一下MPP相关的配置项有没有勾选至少应该能够看到:
1
2
3grep -E \
'^CONFIG_ROCKCHIP_MPP|^CONFIG_ROCKCHIP_IOMMU' \
"$OUT/.config"1
2
3
4CONFIG_ROCKCHIP_MPP_SERVICE=y
CONFIG_ROCKCHIP_MPP_RKVDEC=y
CONFIG_ROCKCHIP_MPP_RKVENC=y
CONFIG_ROCKCHIP_IOMMU=y - (坑)Panther X2其实是没有USB3.0口的,唯一的USB是2.0,不知道为什么mainline的dtsi中有
usb_host0_xhci配置,总之先删掉。
编辑arch/arm64/boot/dts/rockchip/rk3566-panther-x2.dts文件,找到并删除如下内容(看准了再删!!!)1
2
3
4&usb_host0_xhci {
dr_mode = "host";
status = "okay";
}; - (坑)启用
mpp_service,编辑arch/arm64/boot/dts/rockchip/rk3566-panther-x2.dts文件,添加如下节点1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19&mpp_srv {
status = "okay";
};
&rkvdec {
status = "okay";
};
&rkvdec_mmu {
status = "okay";
};
&rkvenc {
status = "okay";
};
&rkvenc_mmu {
status = "okay";
}; - 编译内核和模块
1
2
3
4make O="$OUT" \
ARCH=arm64 \
CROSS_COMPILE=aarch64-linux-gnu- \
-j$(nproc) Image modules - 编译dtb验证:
1
2
3
4make O="$OUT" \
ARCH=arm64 \
CROSS_COMPILE=aarch64-linux-gnu- \
rockchip/rk3566-panther-x2.dtb应该能够看到:1
2
3
4
5
6dtc -I dtb -O dts \
-o /tmp/panther-bsp61.dts \
"$OUT/arch/arm64/boot/dts/rockchip/rk3566-panther-x2.dtb"
grep -n -A4 -B2 "rockchip,mpp-service" \
/tmp/panther-bsp61.dts1
2
3
4
5
6
7701-
702- mpp-srv {
703: compatible = "rockchip,mpp-service";
704- rockchip,taskqueue-count = <0x06>;
705- rockchip,resetgroup-count = <0x06>;
706- status = "okay";
707- phandle = <0x63>;
部署
至此已经完成一大半了,部署这部分基本上就是最简单的了。
1. 在编译机上准备artifacts
- 完善一下参数
1
2
3
4
5
6
7
8
9
10
11
12cd ~/src/linux-bsp61
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
export OUT=$PWD/out
export KREL=$(make -s O="$OUT" \
ARCH=arm64 \
CROSS_COMPILE=aarch64-linux-gnu- \
kernelrelease)
echo "$KREL" - 确认一下配置至少需要有:
1
grep -E '^CONFIG_ROCKCHIP_MPP|^CONFIG_ROCKCHIP_IOMMU' "$OUT/.config"
1
2CONFIG_ROCKCHIP_MPP_SERVICE=y
CONFIG_ROCKCHIP_IOMMU=y - 准备一下模块
1
2
3
4
5
6
7rm -rf stage
make O="$OUT" \
ARCH=arm64 \
CROSS_COMPILE=aarch64-linux-gnu- \
modules_install \
INSTALL_MOD_PATH="$PWD/stage"
2. Panther X2 备份
1 | mkdir -p /root/panther-backup/ |
3. artifact 从编译机复制到 PantherX2
我这里因为PantherX2在内网,编译机在公网,相当于所有文件都是在PantherX2上从编译机上拉取,因此下面的命令都在PantherX2上运行。
1 | scp -C root@<runnerIP>:/root/src/linux-bsp61/out/arch/arm64/boot/Image /root/Image-bsp61 |
注意修改一下最后两行命令末尾及下文命令中的版本号,如果你的版本号跟我的不一样记得改。
4. 安装模块
- 复制文件
1
2
3mkdir -p "/lib/modules/6.1.118-panther-bsp61"
cp -a "/root/modules/6.1.118-panther-bsp61/." "/lib/modules/6.1.118-panther-bsp61/"
install -m 0644 "/root/config-6.1.118-panther-bsp61" "/boot/config-6.1.118-panther-bsp61" - 设置压缩格式采用gzip
1
printf '%s\n' 'COMPRESS=gzip' > /etc/initramfs-tools/conf.d/panther-bsp61
- 更新模块
1
depmod -a 6.1.118-panther-bsp61
- 确认一下模块存在
1
ls -ld "/lib/modules/6.1.118-panther-bsp61"
5. 安装内核
- 复制内核文件
1
install -m 0644 "/root/vmlinuz-6.1.118-panther-bsp61" "/boot/vmlinuz-6.1.118-panther-bsp61"
- 让
/boot/Image指向新内核1
ln -sfn "vmlinuz-6.1.118-panther-bsp61" /boot/Image
- 确认应该返回
1
readlink -f /boot/Image
/boot/vmlinuz-6.1.118-panther-bsp61。
6. 安装dtb
1 | install -m 0644 "/root/rk3566-panther-x2-6.1.118-panther-bsp61.dtb" /boot/dtb/rockchip/rk3566-panther-x2.dtb |
7. 生成initramfs
1 | update-initramfs -c -k 6.1.118-panther-bsp61 |
8. 生成uInitrd
1 | mkimage \ |
9. 重启
重启前进行同步:
1 | sync && reboot |
验证:
1 | root@armbian:/boot# ls -lh /boot/uInitrd-bsp61 |
验收
基本信息
1 | root@armbian:~# uname -a |
ffmpeg测试
- 硬解+硬编:结果:
1
2
3ffmpeg -hwaccel rkmpp -hide_banner -benchmark -stats -c:v h264_rkmpp \
-i \[SubsPlease\]\ Kore\ Kaite\ Shine\ -\ 02\ \(1080p\)\ \[0F910AE6\].mkv \
-map 0:v:0 -an -sn -dn -c:v h264_rkmpp -b:v 8M out.mp4观察到CPU全程负载小于0.25。1
frame= 6848 fps= 26 q=14.0 size= 290048kB time=00:04:45.57 bitrate=8320.3kbits/s speed=1.08x
- 软解(做对比)结果:
1
2
3ffmpeg -hide_banner -benchmark -stats -c:v h264 \
-i \[SubsPlease\]\ Kore\ Kaite\ Shine\ -\ 02\ \(1080p\)\ \[0F910AE6\].mkv \
-map 0:v:0 -an -sn -dn -c:v h264 -b:v 8M out2.mp4观察到CPU负载为2.64。1
frame= 43 fps=1.7 q=24.0 size= 2304kB time=00:00:01.71 bitrate=11037.6kbits/s speed=0.0676x
Tips
mpp_service节点权限修正
当前mpp_serivce节点的权限是:
1 | crw------- 1 root root |
只有 root 能访问。如果需要给第三方程序使用(比如Jellyfin)建议设置为 video 组可访问:
1 | printf '%s\n' \ |
重新登录后确认:
1 | ls -l /dev/mpp_service |
目标权限应类似:
1 | crw-rw---- 1 root video ... |

