基于 Rockchip 开发板的 openEuler 镜像的构建
一次构建
参考流程:https://gitee.com/guningbo__buaa/rockchip/tree/master#rockchip
构建镜像需执行命令:
sudo bash build.sh -n NAME -k KERNEL_URL -b KERNEL_BRANCH -c BOARD_CONFIG -r REPO_INFO -d DTB_NAME -s SPEC
各个参数意义:
1.-n, --name IMAGE_NAME
构建的镜像名称,例如:openEuler-20.03-LTS-Firefly-RK3399-aarch64-alpha1 或 openEuler-21.09-Firefly-RK3399-aarch64-alpha1。
2.-k, --kernel KERNEL_URL
内核源码仓库的项目地址,默认为 https://gitee.com/openeuler/rockchip-kernel.git。可根据需要设置为 git@gitee.com:openeuler/rockchip-kernel.git 或 git@gitee.com:openeuler/kernel.git。
3.-b, --branch KERNEL_BRANCH
内核源码的对应分支,默认为 openEuler-20.03-LTS。下图是可选的:

4.-c, --config BOARD_CONFIG
开发板对应的 defconfig 的文件名称,对应 u-boot/configs 下 BOARD_CONFIG 文件,默认为 firefly-rk3399_defconfig;如需在 RK3588 开发板上使用预编译的 u-boot,可以将此项设置为 none。
5.-r, --repo REPO_INFO
开发源 repo 文件的 URL 或者路径,也可以是开发源中资源库的 baseurl 列表。
6.-d, --device-tree DTB_NAME
内核设备树中的设备名称,和开发板名称有一点区别,对应 kernel/arch/arm64/boot/dts/rockchip 下的 DTB_NAME.dts 文件,默认为 rk3399-firefly。
下面是一些 rk3588 的设备名称:

7.-s, --spec SPEC
构建的镜像版本:
- headless,无图形界面版的镜像。
- xfce,带 Xfce 桌面以及中文字体、输入法等全部配套软件。
- ukui,带 UKUI 桌面及必要的配套软件(不包括中文字体以及输入法)。
- dde,带 DDE 桌面及必要的配套软件(不包括中文字体以及输入法)。
- rpmlist 文件路径,其中包含镜像中要安装的软件列表,内容参考 rpmlist。
默认使用 headless 选项。
8.-h, --help
显示帮助信息。
build.sh 解析
#!/bin/bash
__usage="
Usage: build [OPTIONS]
Build Rockchip bootable images.
The target bootable compressed images will be generated in the build/YYYY-MM-DD folder of the directory where the build script is located.
Options:
-n, --name IMAGE_NAME The Rockchip image name to be built.
-k, --kernel KERNEL_URL The URL of kernel source's repository, which defaults to https://gitee.com/openeuler/rockchip-kernel.git .
-b, --branch KERNEL_BRANCH The branch name of kernel source's repository, which defaults to openEuler-20.03-LTS.
-c, --config BOARD_CONFIG Required! The name of target board which should be a space separated list, which defaults to firefly-rk3399_defconfig.
-r, --repo REPO_INFO The URL/path of target repo file or list of repo's baseurls which should be a space separated list.
-d, --device-tree DTB_NAME Required! The device tree name of target board, which defaults to rk3399-firefly.
-s, --spec SPEC The image's specification: headless, xfce, ukui, dde or the file path of rpmlist. The default is headless.
-h, --help Show command help.
"
help()
{
echo "$__usage"
exit $1
}
used_param() {
echo ""
echo "Default args"
echo "CONFIG_NAME : $config"
echo ""
echo "DTB_NAME : $dtb_name"
echo ""
echo "KERNEL_BRANCH : $branch"
echo ""
}
default_param() {
config=firefly-rk3399_defconfig
dtb_name=rk3399-firefly
branch=openEuler-20.03-LTS
repo_file="https://gitee.com/src-openeuler/openEuler-repos/raw/openEuler-20.03-LTS/generic.repo "
kernel_url="https://gitee.com/openeuler/rockchip-kernel.git "
workdir=$(pwd)/build
board_type=rk3399
name=${branch}-${dtb_name}-aarch64-alpha1
}
save_param() {
if [ -f $workdir/.param_last ]; then
rm $workdir/.param_last
fi
if [ -f $workdir/.param ]; then
mv $workdir/.param $workdir/.param_last
fi
echo "config=$config
dtb_name=$dtb_name
branch=$branch
repo_file=$repo_file
kernel_url=$kernel_url
spec_param=$spec_param" > $workdir/.param
}
deppkg_install() {
dnf makecache
dnf install git wget make gcc bison dtc m4 flex bc openssl-devel tar dosfstools rsync parted dnf-plugins-core tar kpartx diffutils dracut -y
}
parseargs()
{
if [ "x$#" == "x0" ]; then
return 0
fi
while [ "x$#" != "x0" ];
do
if [ "x$1" == "x-h" -o "x$1" == "x--help" ]; then
return 1
elif [ "x$1" == "x" ]; then
shift
elif [ "x$1" == "x-n" -o "x$1" == "x--name" ]; then
name=`echo $2`
shift
shift
elif [ "x$1" == "x-k" -o "x$1" == "x--kernel" ]; then
kernel_url=`echo $2`
shift
shift
elif [ "x$1" == "x-b" -o "x$1" == "x--branch" ]; then
branch=`echo $2`
shift
shift
elif [ "x$1" == "x-c" -o "x$1" == "x--config" ]; then
config=`echo $2`
shift
shift
elif [ "x$1" == "x-r" -o "x$1" == "x--repo" ]; then
repo_file=`echo $2`
shift
shift
elif [ "x$1" == "x-d" -o "x$1" == "x--device-tree" ]; then
dtb_name=`echo $2`
shift
shift
elif [ "x$1" == "x-s" -o "x$1" == "x--spec" ]; then
spec_param=`echo $2`
shift
shift
else
echo `date` - ERROR, UNKNOWN params "$@"
return 2
fi
done
}
buildid=$(date +%Y%m%d%H%M%S)
builddate=${buildid:0:8}
ERROR(){
echo `date` - ERROR, $* | tee -a ${log_dir}/${builddate}.log
}
LOG(){
echo `date` - INFO, $* | tee -a ${log_dir}/${builddate}.log
}
default_param
parseargs "$@" || help $?
used_param
if [ ! -d $workdir ]; then
mkdir $workdir
fi
save_param
if [ ! -d ${log_dir} ];then mkdir -p ${log_dir}; fi
if [ -f $workdir/.done ];then
LOG "Checking the previous build."
if [[ $(cat $workdir/.done | grep u-boot) == "u-boot" && \
$(cat $workdir/.done | grep bootimg) == "bootimg" && \
$(cat $workdir/.done | grep rootfs) == "rootfs" && \
$(cat $workdir/.done | grep image) == "image" ]];then
LOG "Found complete build, clean build flag."
rm $workdir/.done
touch $workdir/.done
fi
else
deppkg_install
touch $workdir/.done
fi
if [[ $(cat $workdir/.done | grep u-boot) != "u-boot" ]];then
bash build_u-boot.sh
fi
if [[ $(cat $workdir/.done | grep bootimg) != "bootimg" ]];then
bash build_boot.sh
fi
if [[ $(cat $workdir/.done | grep rootfs) != "rootfs" ]];then
bash build_rootfs.sh
fi
if [[ "x$dtb_name" == "seawaybox_nj_3588.dts" || "x$dtb_name" == "xrk3588s-roc-pc" || "x$dtb_name" == "xrk3588-firefly-itx-3588j" || "x$dtb_name" == "xrk3588-rock-5b" ]]; then
board_type=rk3588
else
board_type=rk3399
fi
bash gen_image.sh -n $name -t $board_type
自己实验
自己试验阶段:
进入服务器 root@192.168.1.46 ,进入 /home/fan/rockchip/scripts 目录下,执行下面的指令:
[root@localhost scripts]# sudo bash build.sh -n openEuler-22.03-LTS-Station-M3-aarch64-alpha1 -k https://gitee.com/openeuler/rockchip-kernel.git -b openEuler-22.03-LTS-RK3588 -c none -r https://gitee.com/src-openeuler/openEuler-repos/raw/openEuler-22.03-LTS-SP3/generic.repo -d rk3588s-roc-pc -s headless
在当前路径下新生成了 build 目录:
[root@localhost scripts]# ll
总用量 64
drwxr-xr-x 6 root root 4096 9月 9 14:09 bin
drwxr-xr-x 6 root root 4096 9月 9 15:03 build //时间晚于其他,是新生成的
-rwxr-xr-x 1 root root 7811 9月 9 14:09 build_boot.sh
-rwxr-xr-x 1 root root 13682 9月 9 14:09 build_rootfs.sh
-rwxr-xr-x 1 root root 4919 9月 9 14:09 build.sh
-rwxr-xr-x 1 root root 4397 9月 9 14:09 build_u-boot.sh
drwxr-xr-x 2 root root 4096 9月 9 14:09 configs
-rwxr-xr-x 1 root root 7479 9月 9 14:09 gen_image.sh
-rw-r--r-- 1 root root 2122 9月 9 14:09 gen_image-x86_64.sh
build 目录下面内容如下:
[root@localhost build]# ls
2025-09-09 boot.img kernel log rootfs.img u-boot
其中 2025-09-09 中有压缩后的镜像文件:
[root@localhost build]# ls 2025-09-09/
openEuler-22.03-LTS-Station-M3-aarch64-alpha1.img.xz //想要烧录到板子上需要解压缩
openEuler-22.03-LTS-Station-M3-aarch64-alpha1.img.xz.sha256sum
其中 kernel 目录就是内核源码目录,这里为了与板子设备树对应,现在有从其他机器上下载来的对应板子的设备树压缩包,将其解压并到 /home/fan/rockchip/scripts/build/kernel/arch/arm64/boot/dts/rockchip 目录下,之前的目录树文件目录先删除。
[root@localhost dts]# rm -rf rockchip/
[root@localhost dts]# cd /home/fan/
[root@localhost fan]# ls
rockchip rockchip.tar.gz
[root@localhost fan]# tar -xzf rockchip.tar.gz -C /home/fan/rockchip/scripts/build/kernel/arch/arm64/boot/dts/
然后开始烧录,主要借鉴刷写EMMC镜像,步骤如下:
1.本方法适用于 Rk3399/RK3588。
2.刷写所需要的文件:
-
1.生成的刷写文件压缩包为 build 下或项目主页发布的的压缩后的 RAW 原始镜像(需要解压):openEuler-VERSION-BOARD-RELEASE.img.xz 解压到 openEuler-VERSION-BOARD-RELEASE.img
-
2.项目主页 scripts/bin 目录下提供的:
- 如果是 RK3399,使用 rk3399_loader.bin
- 如果是 RK3588,使用 rk3588_loader.bin
3.下载版本不小于 2.92 的 RKDevTool 工具。
原文写的是通过Maskrom模式来进行刷写,这里我的板子有点特殊,不走Maskrom这一套流程
- 使用 Type-C data cable 连接好开发板和主机
- 插上电源线;
- 开发板开机,type c 数据线连接到左边的靠近板子电源的串口,通过串口协议 SERIAL ,登录到开发板



- 进入之后,执行
reboot loader,当看到下面第二张图时,就可以断开 type c和串口的连接,进而插到右边那个串口,用于烧录


- 切换至下载镜像页,勾选需要烧录的分区,可以多选。按照图片顺序进行操作:
--两者地址都为 0x00000000,确保刷入地址正确。
--点击路径右边的空白表格单元格选择:
--如果是 RK3588,选择 rk3588_loader.bin
--点击路径右边的空白表格单元格选择 openEuler-VERSION-BOARD-RELEASE.img。
--双击 system 项目的“储存”栏,选择储存为 EMMC。
--勾选“强制按地址写”。
--点击执行,开始刷写。

其中应为这里已经下载完成,刷写成功了,显示"没有发现设备",在刷写成功之前,会显示"发现一个loader设备"
至此刷写过程结束
将ui打包到镜像中,改变设备树,修改gen脚本,去掉其中压缩镜像的部分
ui加入到镜像中
只需要在参数 -s 后加入想要选择的 ui ,比如这里选择 ukui,带 UKUI 桌面及必要的配套软件(不包括中文字体以及输入法),即 sudo bash build.sh ....... -s ukui
改变设备树
只需要在参数 -d 后加入想要选择的设备树文件即可,这里我们选择 seawaybox_nj_3588.dts ,但是输入参数的时候不用带 .dts 后缀,即 sudo bash build.sh ....... -d seawaybox_nj_3588,但是还没完,在查看 build.sh 中,发现会根据设备树名称来选择 board_type ,而 seawaybox_nj_3588 不在判断列表中,因此需要再修改 build.sh 中的判断列表,如下 "x$dtb_name" == "xseawaybox_nj_3588"为新增的,注意后面的 seawaybox_nj_3588 要加一个 x 前缀,保持和前面 x$dtb_name 的前缀一样
if [[ "x$dtb_name" == "xseawaybox_nj_3588" || "x$dtb_name" == "xrk3588s-roc-pc" || "x$dtb_name" == "xrk3588-firefly-itx-3588j" || "x$dtb_name" == "xrk3588-rock-5b" ]]; then
board_type=rk3588
else
board_type=rk3399
fi
还有就是在 build/kernel/arch/arm64/boot/dts/rockchip/Makefile 文件中新增一行dtb-$(CONFIG_ARCH_ROCKCHIP) += seawaybox_nj_3588.dtb
然后在 build_u-boot.sh 中也新增一行 "x$dtb_name" == "xseawaybox_nj_3588",注意后面的 seawaybox_nj_3588 要加一个 x 前缀,保持和前面 x$dtb_name 的前缀一样
use_prebuild_u-boot() {
if [ -d $workdir/u-boot ]; then
rm -rf $workdir/u-boot
fi
mkdir $workdir/u-boot
if [ -f $workdir/.param ]; then
dtb_name=$(cat $workdir/.param | grep dtb_name)
dtb_name=${dtb_name:9}
if [[ "x$dtb_name" == "xseawaybox_nj_3588" || "x$dtb_name" == "xrk3588s-roc-pc" || "x$dtb_name" == "xrk3588-firefly-itx-3588j" ]]; then
修改gen脚本
注释掉生成.xz压缩包的部分,注释部分如下:
#LOG "xz openEuler image begin..."
#xz ${outputdir}/${name}.img
#if [ ! -f ${outputdir}/${name}.img.xz ]; then
#ERROR "xz openEuler image failed!"
#exit 2
#else
#LOG "xz openEuler image success."
#fi
#sha256sum ${name}.img.xz >> ${name}.img.xz.sha256sum
修改后的命令
我们修改了两个参数 -d,-s,修改了 gen_image.sh 中的脚本,下面执行修改后的指令:
[root@localhost scripts]# sudo bash build.sh -n openEuler-22.03-LTS-Station-M3-aarch64-alpha1 -k https://gitee.com/openeuler/rockchip-kernel.git -b openEuler-22.03-LTS-RK3588 -c none -r https://gitee.com/src-openeuler/openEuler-repos/raw/openEuler-22.03-LTS-SP3/generic.repo -d seawaybox_nj_3588 -s ukui

浙公网安备 33010602011771号