自定义rock5b内核

自定义rock5b内核

官方资料

https://wiki.radxa.com/Rock5/guide/build-debian-from-debos-radxa

官方的资料在这里,打包成deb包,然后进行安装的是没有问题的,手动编译成Image,和dtb的,然后替换的部分,是有问题的,如果严格按照上面的文档的方法手动去更新内核,是启动不起来的,本篇就把这块补充起来

大部分资料是参考官方的即可,小部分是补充的

二者的区别

其实整体上是没有太大的区别的,deb包就是完整的内核替换流程,而手动的就是方便如果只进行部分内核模块的修改的时候,替换模块文件即可,能够做更精细的内核替换

deb的内核更新方式

获取内核代码

1
2
3
4
5
6
7
8
apt-get update
apt-get install git
mkdir ~/rk3588-sdk && cd ~/rk3588-sdk
git clone -b stable-5.10-rock5 https://github.com/radxa/u-boot.git
git clone -b stable-5.10-rock5 https://github.com/radxa/kernel.git
git clone -b master https://github.com/radxa/rkbin.git
git clone -b debian https://github.com/radxa/build.git
git clone -b main https://github.com/radxa/debos-radxa.git

如果是在X86的环境下面编译就按官方文档安装工具链,如果就是在arm64板卡上面进行编译的,就不需要,目前我的编译环境是在arm64下面,就按arm64的写步骤

能够提供arm64编译环境的地方:

  • 1、板卡,rock4b或者rock5b
  • 2、mac M1 安装ubuntu 虚拟机
  • 3、大型的arm64服务器

安装依赖包

1
apt-get install device-tree-compiler libncurses5 libncurses5-dev build-essential libssl-dev mtools bc python dosfstools

打包成deb内核包

1
./build/pack-kernel.sh -d rockchip_linux_defconfig -r 10 # rockchip_linux_defconfig: kernel defconfig; 1: release number

编译完成以后就在下面的这个目录里面有相关的deb包生成,然后去安装即可

1
ls out/packages/

内核启动分析

1
2
3
4
5
6
7
8
9
10
root@rock-5b:~# cat /boot/extlinux/extlinux.conf
timeout 10
menu title select kernel

label kernel-5.10.66-11-rockchip-gc428536281d6
kernel /vmlinuz-5.10.66-11-rockchip-gc428536281d6
initrd /initrd.img-5.10.66-11-rockchip-gc428536281d6
devicetreedir /dtbs/5.10.66-11-rockchip-gc428536281d6
fdtoverlays /dtbs/5.10.66-11-rockchip-gc428536281d6/rockchip/overlay/rk3588-uart7-m2.dtbo
append root=UUID=67ad0e7b-3914-48d6-97c2-c48e5e0e405b earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 console=tty1 consoleblank=0 loglevel=0 panic=10 rootwait rw init=/sbin/init rootfstype=ext4 cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory swapaccount=1 irqchip.gicv3_pseudo_nmi=0 switolb=1 coherent_pool=2M

这个就是板卡的启动控制文件,这个跟x86的那个grub也是类似的,都是加载模块,然后根据指定的参数启动

  • kernel 就是内核,启动的时候加载的
  • initrd 这个是根据/lib/modules/kernel生成的,是内核的一些模块,我们编译内核的时候*就是放在内核里面,M的模块就是放在了modules里面,然后生成的initrd可以在启动的时候加载这部分的内核
  • devicetreedir 这个就是dtbs设备树
  • fdtoverlays 这部分是补充的一部分的
  • append 是启动的控制参数部分

deb包的是会自己处理好这部分的,但是手动的,可以看到只提供了Image和fdt两个,单纯使用这两个是启动不了内核的,因为sdk提供的内核里面把一些模块是按module的方式处理的,Image里面并没有这部分,也就无法正常的启动了

手动替换方法

下载内核

1
git clone -b stable-5.10-rock5 https://github.com/radxa/kernel.git

检查内核

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
root@ubuntu:~/rk3588-sdk/kernel# git log
commit c428536281d69aeb2b3480f65b2b227210b61535 (HEAD -> stable-5.10-rock5, origin/stable-5.10-rock5)
Author: 忘怀 <[email protected]>
Date: Tue Nov 1 09:08:05 2022 +0800

rockchip_linux_defconfig: add Kubernetes support2 (#36)

To support kubernetes and bring more Networking feature,
Need to open more Network supports.
NETFILTER sets、MT_TCP、TLS、TCPacc、802.1d
Fix issue : rockchip-linux#273

# Network packet filtering framework (Netfilter)
CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
CONFIG_NETFILTER_XT_TARGET_DSCP=m
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
CONFIG_NETFILTER_XT_TARGET_TRACE=m
CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m

可以看到最新的是解决了k8s的运行问题,缺了一些模块,官方开启了相关的模块

编译内核

1
2
3
4
cd /root/rk3588-sdk/kernel
make kernelversion
make rockchip_linux_defconfig
make -j24

上面的rockchip_linux_defconfig文件路径为arch/arm64/configs/rockchip_linux_defconfig,这个就是内核的配置文件,开启了这些配置,如果需要更改这个默认的配置就按下面的流程,官方的脚本是调用的这个默认配置,如果是自己手动编译,就直接修改即可
上面的编译完成以后,并没有结束,我们需要提取我们需要的东西,官方的文档是Image和dtb文件,我们按照deb包里面的进行提取

修改默认内核配置

1
2
3
make menuconfig
make savedefconfig
cp defconfig arch/arm64/configs/rockchip_linux_defconfig

提取内核输出

这个步骤就是上面的编译完成以后我们需要提取的东西,按下面的步骤操作

1
2
3
4
mkdir /tmp/out/
export INSTALL_PATH=/tmp/out/; make install
export INSTALL_PATH=/tmp/out/; make dtbs_install
export INSTALL_MOD_PATH=/tmp/out;make modules_install
  • 上面的第一个install 是安装的内核vmlinuz文件
  • 第二个dtbs_install 是安装的dtbs相关的
  • 第三个modules_install 是安装的内核模块的文件

默认的打出来的版本号是5.10.66-267892-gc428536281d6,

1
out/lib/modules/5.10.66-267892-gc428536281d6

为了避免冲突或者错误的替换,我们自己加入自己需要的版本信息

内核的版本信息在这里面

1
cat kernel/include/generated/utsrelease.h 

是根据makefile和.config生成的

1
2
3
root@ubuntu:~/rk3588-sdk/kernel# make -j 48
UPD include/config/kernel.release
UPD include/generated/utsrelease.h
1
2
3
4
5
6
7
root@ubuntu:~/rk3588-sdk/kernel# head  -n 10 Makefile
# SPDX-License-Identifier: GPL-2.0
VERSION = 5
PATCHLEVEL = 10
SUBLEVEL = 66
EXTRAVERSION = -zp1
NAME = Dare mighty thing

我们在makefile里面增加EXTRAVERSION = -zp1

上面的操作以后我们得到的就是下面的这些,我们拷贝到rock5b的机器上

1
2
3
4
5
6
7
8
9
root@ubuntu:~# ll /tmp/out/
total 37040
drwxr-xr-x 4 root root 4096 Nov 24 07:21 ./
drwxrwxrwt 14 root root 4096 Nov 24 07:22 ../
-rw-r--r-- 1 root root 210401 Nov 24 07:20 config-5.10.66-zp1-267892-gc428536281d6-dirty
drwxr-xr-x 3 root root 4096 Nov 24 07:21 dtbs/
drwxr-xr-x 3 root root 4096 Nov 24 07:21 lib/
-rw-r--r-- 1 root root 7165888 Nov 24 07:20 System.map-5.10.66-zp1-267892-gc428536281d6-dirty
-rw-r--r-- 1 root root 30530048 Nov 24 07:20 vmlinuz-5.10.66-zp1-267892-gc428536281d6-dirty

安装内核

拷贝模块

1
cp -ra lib/modules/5.10.66-zp1-267892-gc428536281d6-dirty/ /lib/modules/

半自动处理方式

1
2
3
4
mkdir /usr/lib/linux-image-5.10.66-zp1-267892-gc428536281d6-dirty
cp -ra vmlinuz-5.10.66-zp1-267892-gc428536281d6-dirty /boot/
cp -ra dtbs/5.10.66-zp1-267892-gc428536281d6-dirty/rockchip /usr/lib/linux-image-5.10.66-zp1-267892-gc428536281d6-dirty
run-parts --arg="5.10.66-zp1-267892-gc428536281d6-dirty" --arg="/boot/vmlinuz-5.10.66-zp1-267892-gc428536281d6-dirty" /etc/kernel/postinst.d

上面的run-parts脚本
做了下面几个工作:

  • 1、生成了(/boot/initrd.img-5.10.66-zp1-267892-gc428536281d6-dirty)
  • 2、把/usr/lib/linux-image-5.10.66-zp1-267892-gc428536281d6-dirty里面的dtb拷贝到dtbs里面
  • 3、更新extlinux.conf脚本

纯手动处理方式

拷贝文件

1
2
3
4
cp -ra dtbs/5.10.66-zp1-267892-gc428536281d6-dirty/ /boot/dtbs/
cp -ra vmlinuz-5.10.66-zp1-267892-gc428536281d6-dirty /boot/
cp -ra System.map-5.10.66-zp1-267892-gc428536281d6-dirty /boot/
cp -ra config-5.10.66-zp1-267892-gc428536281d6-dirty /boot/

生成initrd

1
2
root@rock-5b:~/zp/out# update-initramfs -k 5.10.66-zp1-267892-gc428536281d6-dirty -c
update-initramfs: Generating /boot/initrd.img-5.10.66-zp1-267892-gc428536281d6-dirty

编写/boot/extlinux/extlinux.conf文件

上面的手工部分是通过解压官方的image查看到的脚本

1
2
dpkg -e linux-image-5.10.66-11-rockchip-gc428536281d6_5.10.66-11-rockchip_arm64.deb debian/
cat debian/postinst

内核启动脚本内核

1
2
3
4
5
6
7
8
9
10
root@rock-5b:/boot# cat /boot/extlinux/extlinux.conf
#timeout 10
#menu title select kernel

label kernel-5.10.66-zp1-267892-gc428536281d6-dirty
kernel /vmlinuz-5.10.66-zp1-267892-gc428536281d6-dirty
initrd /initrd.img-5.10.66-zp1-267892-gc428536281d6-dirty
devicetreedir /dtbs/5.10.66-zp1-267892-gc428536281d6-dirty
fdtoverlays /dtbs/5.10.66-zp1-267892-gc428536281d6-dirty/rockchip/overlay/rk3588-uart7-m2.dtbo
append root=UUID=67ad0e7b-3914-48d6-97c2-c48e5e0e405b earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 console=tty1 consoleblank=0 loglevel=0 panic=10 rootwait rw init=/sbin/init rootfstype=ext4 cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory swapaccount=1 irqchip.gicv3_pseudo_nmi=0 switolb=1 coherent_pool=2M

重启后检查

1
2
root@rock-5b:~# uname  -a
Linux rock-5b 5.10.66-zp1-267892-gc428536281d6-dirty #2 SMP Thu Nov 24 04:26:01 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux

可以看到内核已经替换好了