嵌入式ARM64 基于RK3588原生SDK添加用户配置选项build lunch
1 背景
在我们正常拿到SDK后会有一些配置选项,在使用./build.sh lunch之后会输出一些defautconfig让我们选择,瑞芯微的原厂sdk会提供一些主板的配置选项,但是我们的如果是一块新的主板就需要添加自己的配置选项,本文就讨论如何来添加自己的板卡配置选项。
2 配置介绍
正常我们配置一套linux系统需要配的目标有uboot,Linux,rootfs,一般情况uboot我们不需要去管,这都是sdk里面做好的,不需要怎么修改。我们需要配的是Liunx的内核和rootfs这两部分。
以我使用的rk3588_linux6.1_release_v1.2.0_20241220这套sdk为例,使用./build会出现下列选项:
./build.sh lunch
Log colors: message notice warning error fatalLog saved at /home/lubancat/rk3588/rk3588_linux6.1_release_v1.2.0_20241220/output/sessions/2025-09-05_02-15-22
Pick a defconfig:1. rockchip_defconfig
2. rockchip_rk3588_evb1_lp4_v10_defconfig
3. rockchip_rk3588_evb7_v11_defconfig
4. rockchip_rk3588_ipc_evb1_v10_defconfig
5. rockchip_rk3588_multi_ipc_evb1_v10_defconfig
6. rockchip_rk3588s_evb1_lp4x_v10_defconfig
Which would you like? [1]:
这些选项都是瑞芯微官方主板的一些配置,如果我们直接在这些官方配置里面去改回比较乱,很容易搞混,目标是添加自己的配置又不想去修改原本的。想做到这一点是需要我们去搞懂他这个sdk自动化编译的逻辑。
在 Rockchip 提供的 Android/Linux SDK 里,顶层通常有一个 build.sh 脚本,用来封装编译流程,类似于 Android AOSP 的 lunch + make。它的主要功能包括:设置环境变量、调用 lunch(选择目标平台/产品/编译模式)、调用 make 或 m 执行编译、打包生成最终的固件(boot.img, system.img, update.img 等)。
但是我们打开build.sh查看后发现没有lunch这个函数,实际上现在都是通过build-hook机制,在main()有一句run_build_hooks init $OPTIONS实际执行的相当于是run_build_hooks init lunch,然后执行run_hooks "$RK_BUILD_HOOK_DIR" init lunch,这里RK_BUILD_HOOK_DIR=device/rockchip/common/build-hooks相当于run_hooks对这个目录下的所有脚本进行遍历,对所有的脚本执行hook_check看是否支持init lunch命令
run_hooks()
{DIR="$1"shift # 参数变成:init lunch# Prefer chips' hooks than the common onesfor dir in "$RK_CHIP_DIR/$(basename "$DIR")/" "$DIR"; do[ -d "$dir" ] || continuefor hook in $(find "$dir" -maxdepth 1 -name "*.sh" | sort); do# Ignore unrelated hookshook_check "$hook" "$1" "$2" || continueif ! "$hook" $@; then...fidonedone
}hook_check()
{case "$2" ininit | pre-build | build | post-build) ;;*) return 0 ;;esacCMDS="$(sed -n \"s@^RK_${2//-/_}_CMDS[^ ]*\(.*\)\" # $(realpath "$1")\$@\1@ip" \"$RK_PARSED_CMDS")"if echo "$CMDS" | grep -wq default; thenreturn 0fioption_check "$CMDS" "$3"
}
hook_check()这里关键在 $RK_PARSED_CMDS,它是 output/.parsed_cmds 文件,里面记录了哪些 hook 脚本支持哪些命令。比如 mk-config.sh 里声明了
INIT_CMDS="chip defconfig lunch [^:]*_defconfig ..." 这会被解析进 $RK_PARSED_CMDS
最后 hook_check()去执行:device/rockchip/common/scripts/mk-config.sh init lunch
在mk-config.sh的末尾有init_hook $@,相当于执行 init_hook init lunch,在init_hook里面有lunch|defconfig) shift; choose_defconfig $@ ;; 相当于执行choose_defconfig lunch这就进入了选择defconfig菜单。
rockchip_defconfigs()
{cd "$RK_CHIP_DIR"ls rockchip_defconfig 2>/dev/null || truels *_defconfig | grep -v rockchip_defconfig || true
}choose_defconfig()
{DEFCONFIG_ARRAY=( $(rockchip_defconfigs | grep "$1" || true) )DEFCONFIG_ARRAY_LEN=${#DEFCONFIG_ARRAY[@]}case $DEFCONFIG_ARRAY_LEN in0)error "No available defconfigs${1:+" for: $1"}"return 1;;1) DEFCONFIG=${DEFCONFIG_ARRAY[0]} ;;*)if [ "$1" = ${DEFCONFIG_ARRAY[0]} ]; then# Prefer exact-matchDEFCONFIG="$1"elsemessage "Pick a defconfig:\n"echo ${DEFCONFIG_ARRAY[@]} | xargs -n 1 | \sed "=" | sed "N;s/\n/. /"local INDEXread -p "Which would you like? [1]: " INDEXINDEX=$((${INDEX:-1} - 1))DEFCONFIG="${DEFCONFIG_ARRAY[$INDEX]}"fi;;esacswitch_defconfig $DEFCONFIG
}INIT_CMDS="chip defconfig lunch [^:]*_defconfig olddefconfig savedefconfig menuconfig config default"
init_hook()
{case "${1:-default}" inchip) shift; choose_chip $@ ;;lunch|defconfig) shift; choose_defconfig $@ ;;*_defconfig) switch_defconfig "$1" ;;olddefconfig | savedefconfig | menuconfig)prepare_configmake $1;;config)prepare_configmake menuconfigmake savedefconfig;;default) prepare_config ;; # End of init*) usage ;;esac
}source "${RK_BUILD_HELPER:-$(dirname "$(realpath "$0")")/../build-hooks/build-helper}"init_hook $@
choose_defconfig()会通过rockchip_defconfigs()搜集.chip目录下后缀为_defconfig的文件放到DEFCONFIG_ARRAY数组,然后打印出来,当我们选择之后会通过switch_defconfig()函数将配置文件保存到output/.config里面。
3 增加配置
我们先查看一下.chip下面有什么文件,我们先用ls -la命令查看一下device/rockchip下面有哪些目录:
$ ls device/rockchip/ -la
total 24
drwxrwxr-x 5 lubancat lubancat 4096 Sep 5 02:31 .
drwxrwxr-x 3 lubancat lubancat 4096 Sep 3 04:10 ..
lrwxrwxrwx 1 lubancat lubancat 13 Sep 5 02:31 .chip -> .chips/rk3588
drwxrwxr-x 3 lubancat lubancat 4096 Sep 3 04:10 .chips
drwxrwxr-x 13 lubancat lubancat 4096 Sep 3 04:10 common
drwxrwxr-x 2 lubancat lubancat 4096 Sep 3 04:10 .git
-rw-rw-r-- 1 lubancat lubancat 24 Sep 3 04:10 .gitignore
lrwxrwxrwx 1 lubancat lubancat 13 Sep 5 02:31 rk3588 -> .chips/rk3588
经过查看发现.chip和rk3588这两个目录都是链接到.chips/rk3588里面的,所以我们真正需要关注是.chips/rk3588目录:
$ ls device/rockchip/.chips/rk3588/ -l
total 48
-rw-rw-r-- 1 lubancat lubancat 1708 Sep 3 04:10 amp_linux.its
-rw-rw-r-- 1 lubancat lubancat 1365 Sep 3 04:10 amp_mcu.its
-rw-rw-r-- 1 lubancat lubancat 1673 Sep 3 04:10 boot4recovery.its
-rw-rw-r-- 1 lubancat lubancat 1430 Sep 3 04:10 boot.its
-rw-rw-r-- 1 lubancat lubancat 477 Sep 3 04:10 parameter-ab.txt
-rw-rw-r-- 1 lubancat lubancat 539 Sep 3 04:10 parameter.txt
lrwxrwxrwx 1 lubancat lubancat 34 Sep 3 04:10 rockchip_defconfig -> rockchip_rk3588_evb7_v11_defconfig
-rw-rw-r-- 1 lubancat lubancat 64 Sep 3 04:10 rockchip_rk3588_evb1_lp4_v10_defconfig
-rw-rw-r-- 1 lubancat lubancat 60 Sep 3 04:10 rockchip_rk3588_evb7_v11_defconfig
-rw-rw-r-- 1 lubancat lubancat 103 Sep 3 04:10 rockchip_rk3588_ipc_evb1_v10_defconfig
-rw-rw-r-- 1 lubancat lubancat 112 Sep 3 04:10 rockchip_rk3588_multi_ipc_evb1_v10_defconfig
-rw-rw-r-- 1 lubancat lubancat 66 Sep 3 04:10 rockchip_rk3588s_evb1_lp4x_v10_defconfig
-rw-rw-r-- 1 lubancat lubancat 1429 Sep 3 04:10 zboot.its
这里有很多代_defconfig后缀的文件,我们打开一个看一下:
$ vi device/rockchip/.chips/rk3588/rockchip_rk3588_evb7_v11_defconfig
RK_KERNEL_DTS_NAME="rk3588-evb7-v11-linux"
RK_USE_FIT_IMG=y
这里其实很简单就是指定了一个RK_KERNEL_DTS_NAME变量,这个变量表明了要编译的内核配置文件。我们新建一个配置文件,将刚才的那个文件改个名字就行了,然后将RK_KERNEL_DTS_NAME改为"yz3588-aiot-v10"
cp device/rockchip/.chips/rk3588/rockchip_rk3588_evb7_v11_defconfig device/rockchip/.chips/rk3588/rockchip_rk3588_yeezi_v10_defconfig
lubancat@ubuntu:/opt/rk3588_linux6.1_release_v1.2.0_20241220$
$ vi device/rockchip/.chips/rk3588/yz3588_defconfig
RK_KERNEL_DTS_NAME="yz3588-aiot-v10"
RK_USE_FIT_IMG=y
这个时候我们再执行./build.sh lunch会发现多了一个选项:
$ ./build.sh lunch
Log colors: message notice warning error fatalLog saved at /home/lubancat/rk3588/rk3588_linux6.1_release_v1.2.0_20241220/output/sessions/2025-09-05_02-51-27
Pick a defconfig:1. rockchip_defconfig
2. rockchip_rk3588_evb1_lp4_v10_defconfig
3. rockchip_rk3588_evb7_v11_defconfig
4. rockchip_rk3588_ipc_evb1_v10_defconfig
5. rockchip_rk3588_multi_ipc_evb1_v10_defconfig
6. rockchip_rk3588s_evb1_lp4x_v10_defconfig
7. rockchip_rk3588_yeezi_v10_defconfig
Which would you like? [1]:
我们的初始配置已经添加成功。
3.1 Linux内核配置
现在说一下刚才RK_KERNEL_DTS_NAME这个文件的作用,在Linux内核配置中主要是通过dts文件去配置设备树,通过设备树去选择哪些设备需要打开,哪些需要配什么功能。瑞芯微sdk的设备树目录是在kernel/arch/arm64/boot/dts/rockchip/这个目录下,通过ls查看发现有很多rk3588开头的dts和dtsi文件
...
-rw-rw-r-- 24364 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5.dtsi
-rw-rw-r-- 339 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10.dts
-rw-rw-r-- 1886 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp.dts
-rw-rw-r-- 1890 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-edp-linux.dts
-rw-rw-r-- 337 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5-v10-linux.dts
-rw-rw-r-- 9586 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb4-lp4.dtsi
-rw-rw-r-- 304 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb4-lp4-v10.dts
-rw-rw-r-- 302 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb4-lp4-v10-linux.dts
-rw-rw-r-- 5287 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb5-lp4.dtsi
-rw-rw-r-- 304 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb5-lp4-v10.dts
-rw-rw-r-- 302 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb5-lp4-v10-linux.dts
-rw-rw-r-- 9554 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb6-lp4.dtsi
-rw-rw-r-- 304 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb6-lp4-v10.dts
-rw-rw-r-- 302 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb6-lp4-v10-linux.dts
-rw-rw-r-- 21798 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-cam-8x.dtsi
-rw-rw-r-- 2710 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-imx415.dtsi
-rw-rw-r-- 17498 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-lp4.dtsi
-rw-rw-r-- 339 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-lp4-v10.dts
-rw-rw-r-- 337 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-lp4-v10-linux.dts
-rw-rw-r-- 2038 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-lp4-v10-rk1608-ipc-8x-linux.dts
-rw-rw-r-- 345 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-lp4-v11-linux-ipc.dts
-rw-rw-r-- 335 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11.dts
-rw-rw-r-- 19537 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11.dtsi
-rw-rw-r-- 2710 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11-imx415.dtsi
-rw-rw-r-- 287281 Sep 3 04:28 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11-linux.dtb
-rw-rw-r-- 333 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11-linux.dts
-rw-rw-r-- 3657 Sep 3 04:10 kernel/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11-rk628-hdmi2csi.dts
...
通过前面的配置发现defconfig调用的是rk3588-evb7-v11-linux.dts文件,打开这个文件:
#include "rk3588-evb7-v11.dtsi"
#include "rk3588-evb7-v11-imx415.dtsi"
#include "rk3588-linux.dtsi"/ {model = "Rockchip RK3588 EVB7 V11 Board";compatible = "rockchip,rk3588-evb7-v11", "rockchip,rk3588";
};
这个文件调用了三个头文件,其中rk3588-linux.dtsi是通用的头文件不需要改,我们选择rk3588-evb7-v11版本改为自己主板的名字,通过复制原有的配置来进行修改比较简单,将rk3588-evb7-v11*开头的文件复制一下得到3个文件,并修改yz3588-aiot-v10-linux.dts文件
$ ls kernel/arch/arm64/boot/dts/rockchip -l
-rw-rw-r-- 1 lubancat lubancat 19537 Sep 5 03:04 yz3588-aiot-v10.dtsi
-rw-rw-r-- 1 lubancat lubancat 2710 Sep 5 03:04 yz3588-aiot-v10-imx415.dtsi
-rw-rw-r-- 1 lubancat lubancat 321 Sep 5 03:12 yz3588-aiot-v10-linux.dts$ vi kernel/arch/arm64/boot/dts/rockchip/yz3588-aiot-v10-linux.dts
#include "yz3588-aiot-v10.dtsi"
#include "yz3588-aiot-v10-imx415.dtsi"
#include "rk3588-linux.dtsi"/ {model = "Rockchip RK3588 EVB7 V11 Board";compatible = "rockchip,yz3588-aiot-v10", "rockchip,rk3588";
};
这个文件就是我们再defconfig中调用的文件
3.2 Rootfs配置
默认在执行build.sh不选择系统的时候是指向的是buildroot,如果要改操作系统就需要更改配置,
$ vi device/rockchip/common/scripts/mk-rootfs.sh
build_hook()
{check_config RK_ROOTFS || falseif [ -z "$1" -o "$1" = rootfs ]; thenROOTFS=${RK_ROOTFS_SYSTEM:-buildroot}elseROOTFS=$1fi
我这里改为使用debian系统,所以就需要修改defconfig选项
$ vi device/rockchip/.chips/rk3588/rockchip_rk3588_yeezi_v10_defconfig
RK_KERNEL_DTS_NAME="yz3588-aiot-linux"
RK_USE_FIT_IMG=y
RK_ROOTFS_SYSTEM_DEBIAN=y
添加RK_ROOTFS_SYSTEM_DEBIAN=y这就打开了debian系统,然后我们进行编译测试