armsom-bsp
项目概述
ArmSoM 是一个开源硬件品牌,我们承诺为开源社区提供一流的硬件、强大的固件和详尽的文档,
本文档以armsom板卡armsom-sige5为例主要讲解如何在armsom板卡上开发、部署以及备份量产自己想要的应用
armsom-sdk
armsom-sdk是基于瑞芯微通用Linux SDK工程的定制版本,为RK3588/RK3576主控开发板提供完整的嵌入式Linux BSP支持。
整个SDK工程,目录包含有 debian、kernel、u-boot、device、rkbin、ubuntu等目录。 每个目录或其子目录会对应一个 git 工程,开发提交会在各自的目录下进行。
-
debian12:debian12根文件系统构建脚本,搭配Kernel-6.1使用。
-
device/rockchip: 存放各芯片板级配置,以及构建进行相关的脚本等。
-
kernel-6.1: 存放 kernel 6.1版本 源码。
-
prebuilts: 存放交叉编译工具链。
-
rkbin: 存放 Rockchip 相关的 Binary 和工具。
-
rockdev: 存放编译输出的镜像文件(软链接到output/firmware)。
-
output: 存放编译过程中生成的过程文件、日志、编译出的镜像等。
-
output-release:存放编译完成并归档后的系统镜像
-
tools: 存放 Linux 和 Windows 操作系统环境下常用工具。
-
u-boot:存放基于v2017.09版本进行开发的uboot代码。
-
ubuntu22.04: Ubuntu 22.04 根文件系统构建脚本,搭配Kernel-6.1使用。
SDK 开发环境搭建
开发环境说明如下:
armsom-sdk是基于Ubuntu系统开发测试的,在开发过程中,主要是用Ubuntu22.04版本, 推荐用户使用Ubuntu20.04或Ubuntu22.04。
PC系统默认使用Win11,在使用RockChip的烧录工具时需要使用到Windows系统。,
硬件配置推荐:64位系统,硬盘空间⼤于80G。如果您进⾏多个构建,将需要更⼤的硬盘空间。
安装SDK依赖的软件包
安装SDK构建所需要的软件包,整体复制下面内容到终端中安装:
sudo apt-get update && sudo apt-get install git ssh make gcc libssl-dev \
liblz4-tool expect expect-dev g++ patchelf chrpath gawk texinfo chrpath \
diffstat binfmt-support qemu-user-static live-build bison flex fakeroot \
cmake gcc-multilib g++-multilib unzip device-tree-compiler ncurses-dev \
libgucharmap-2-90-dev bzip2 expat gpgv2 cpp-aarch64-linux-gnu libgmp-dev \
libmpc-dev bc python-is-python3 python3-pip python2 u-boot-tools curl \
python3-pyelftools dpkg-dev
安装repo
armsom-sdk是⽤repo来下载、管理项⽬的软件仓库
mkdir ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
echo PATH=~/bin:$PATH >> ~/.bashrc
source ~/.bashrc

执行完上面的命令后来验证repo是否安装成功能正常运行

Git配置
设置自己的git信息,以确保后续拉取代码时正常进行,如果不需要提交代码的话可以随意设置用户名和邮箱地址
git config --global user.name "your name"
git config --global user.email "your mail"
切换Python 3
#查看当前Python版本 python -V
若返回的版本号为Python3版本,则无需再切换Python版本。若为Python2版本或未发现python,则可以用以下方式切换:
#查看当前系统安装的Python版本有哪些
ls /usr/bin/python*
#将python链接到python3
sudo ln -sf /usr/bin/python3 /usr/bin/python
#重新查看默认Python版本
python -V

SDK源码获取
armsom-sdk的代码被划分为了若干git仓库分别进行版本管理, 可以使用repo工具对这些git仓库进行统一的下载,提交,切换分支等操作。
运行以下命令,将在当前用户的家目录下创建一个名为LubanCat_SDK的目录,用来放入SDK源码。
mkdir ~/armsom-sdk
cd armsom-sdk
repo init -u https://github.com/as-jackson/manifests.git -b linux -m armsom_linux_generic.xml
.repo/repo/repo sync -c -j4
SDK更新
我们会对armsom-sdk不断更新,将修改的内容实时同步到Github,欢迎广大开发爱好者共同来管理维护开源代码, 需要在本地同步更新内容,则可以借助repo或git来实现
使用repo更新整个SDK
首先要更新.repo/manifests,里面保存了repo的配置文件,记录了仓库的版本信息。
# 进入.repo/manifests目录
cd .repo/manifests
# 切换分支到Linux
git checkout linux
# 拉取最新的manifests
git pull
#进入SDK顶层文件夹
cd ~/LubanCat_SDK
# 同步远端仓库
.repo/repo/repo sync -c
使用Git更新单独的源码仓库
有时只想更新某个仓库,而不是去更新整个SDK。 或者已经对SDK的某些仓库做出了修改,使用repo同步的话就会失败。 此时就需要对单个仓库进行更新了
这里以debain12仓库为例:
# 进入debain12目录下
cd debain12
# 检出到对应仓库的默认分支
git checkout lbc-develop-5.10
# 拉取git仓库
git pull
自动构建固件
以下文档以使用rk3576主芯片的sige5板卡为例,使用其他型号芯片的板卡操作方法类似。
在SDK顶层文件夹下,执行以下命令,以选择要构建的板卡主芯片型号和SDK的配置文件。
执行下面命令选择配置芯片以及配置文件
./build.sh chip

当选择完配置文件以后,会使用粉色提示字体提示当前配置文件所用的内核版本
一键编译u-Boot,kernel,Rootfs并打包为update.img镜像
./build.sh
构建好的镜像保存在rockdev/目录下。
分步构建固件
在初次编译固件时需要运行一键构建固件,但是在在进行固件开发时,建议使用分区构建,使用SDK单个模块构建的功能。
选择SDK配置文件
首先,还是要选择SDK的配置文件,如果已经自动编译过则这一步可以跳过,这里以sige5系列板卡的debian系统gnome桌面镜像为例
选择SDK配置文件
./build.sh LubanCat_rk3588_debian_gnome_defconfig
U-Boot构建
./build.sh uboot
构建生成的U-boot镜像为u-boot/uboot.img
Kernel构建
boot分区内核镜像,先生成内核deb包,然后再编译内核并将生成的deb包打包进boot分区。
按顺序执行以下命令,将自动完成 kernel 的构建及打包。
./build.sh kernel
构建生成的kernel镜像为kernel/extboot.img
rootfs构建
SDK主要支持Ubuntu、Debian,当然其他系统也支持但是不在此说明
Ubuntu、Debian支持不同的桌面版本,在前面选择SDK配置文件时已经指定了
构建Debian
./build.sh debian
构建Ubuntu
./build.sh ubuntu
系统镜像的名称重命名为linaro-(SOC型号)-(桌面版本)-rootfs.img,如linaro-rk3576-gnome-rootfs.img
镜像打包
当u-boot,kernel,Rootfs都构建完成以后,需要再执行 ./build.sh firmware 进行固件打包, 主要是检查分区表文件是否存在,各个分区是否与分区表配置对应,并根据配置文件将所有的文件复制或链接到rockdev/内。
固件打包
./build.sh firmware
生成update.img
./build.sh updateimg
烧写固件
烧写固件所需要的工具都在armsom-sdk/tools下面,开发板启动镜像分为emmc启动和sdcard启动
eMMC启动镜像烧录
开发板上都会有烧录口,使用USB线连接PC机与开发板,使用rockchip提供的烧录工具烧录镜像,这里有两种方式,一个是使用瑞芯微开发工具RKDevTool(Windows版)或Linux_Upgrade_Tool(Linux版),RKDevTool和Linux_Upgrade_Tool适合开发时使用或小批量烧录使用
RKDevTool
在window下安装DriverAssitant_v5.13.zip和RKDevTool_Release_v3.37.zip
具体使用参考系统镜像烧录
Linux_Upgrade_Tool
对于在本地Linux操作系统PC上或Linux虚拟机上进行开发的用户而言, Linux_Upgrade_Tool工具用起来不需要切换操作系统环境,使用起来十分便利。
Linux开发工具
sdk里可以获取命令工具

验证工具是否正常使用,返回版本号则正常
upgrade_tool -V
查看下载工具的使用信息
upgrade_tool -h
查看连接到PC的板卡
我们使用USB线连接PC机与开发板,按住maskrom按键然后上电,待板卡进入下载模式。
输入以下命令,查看是否有板卡连接
upgrade_tool LD

根据打印出的信息我们可以得知,目前已经连接了一个设备,他的设备序号是1,ID是11,目前处于Maskrom模式
板卡正确连接以后,我们就可以进行固件的烧录了
烧录完整镜像
完整固件存放在rockdev目录,直接烧录完整镜像到板卡,烧录前要确认板卡处于Maskrom模式
烧录完整镜像
upgrade_tool uf update.img

注意:这里如果报错Creating Comm Object failed!是由于串口权限的问题加上sudo就行
烧录完成后板卡会自动重启
烧录分区镜像
在rockdev目录,将分区镜像到板卡,烧录前要确认板卡处于Maskrom模式
烧录loader不重启设备,不论下载哪个分区都要执行
upgrade_tool ul MiniLoaderAll.bin -noreset
下载分区表
upgrade_tool di -p parameter.txt
下载单独分区,一条命令下载一个分区
upgrade_tool di -u uboot.img
upgrade_tool di -b boot.img
upgrade_tool di -r recovery.img
upgrade_tool di -m misc.img
upgrade_tool di -oem oem.img
upgrade_tool di -userdata userdata.img
upgrade_tool di -rootfs rootfs.img
连续下载多个分区
upgrade_tool di -u uboot.img -b boot.img
重启
upgrade_tool rd
SD卡启动镜像烧录
SD卡的烧录我们目前只支持使用瑞芯微SD卡烧录工具SDDiskTool,由于瑞芯微SD卡烧录工具SDDiskTool目前只有Windows版本,所以SD卡的烧录过程只能在Windows下进行。
烧录工具是armsom-sdk/tools/windows/SDDiskTool_v1.78.zip,

将U盘插入之后会自动识别设备,选择SD启动以及选择固件之后就可以创建SD启动卡了
高级配置与定制
我们提供的固件已经满足绝大多数功能要求了,但是对于一些需要定制功能的客户来说不一定有他们需要的所有功能配置,所以下面讲解如何配置且重构固件
内核模块开发
内核源码目录如下:
armsom@armsom:~/armsom-sdk/kernel-6.1$ ls
COPYING MAINTAINERS certs io_uring mm sound
CREDITS Makefile crypto ipc net tools
Documentation README drivers kernel rust usr
Kbuild arch fs lib samples virt
Kconfig block include logo.bmp scripts
LICENSES boot.its init logo_kernel.bmp security
Linux内核源码目录下是有非常多的目录
-
arch :主要包含和硬件体系结构相关的代码,如arm、x86、MIPS,PPC,每种CPU平台占一个相应的目录。arch中的目录下存放的是各个平台以及各个平台的芯片对Linux内核进程调度、内存管理、 中断等的支持,以及每个具体的SoC和电路板的板级支持代码。
-
block :在Linux中block表示块设备(以块(多个字节组成的整体,类似于扇区)为单位来整体访问),譬如说SD卡、Nand、硬盘等都是块设备,block目录下放的是一些Linux存储体系中关于块设备管理的代码。
-
crypto :这个目录下存放的是常用加密和散列算法(如md5、AES、 SHA等),还有一些压缩和CRC校验算法。
-
Documentation:内核各部分的文档描述。
-
drivers :设备驱动程序,里面列出了linux内核支持的所有硬件设备的驱动源代码,每个不同的驱动占用一个子目录,如char、block、 net、 mtd、 i2c等。
-
fs :fs就是file system,里面包含Linux所支持的各种文件系统,如EXT、FAT、 NTFS、 JFFS2等。
-
include :目录包括编译核心所需要的大部分头文件,例如与平台无关的头文件在 include/linux 子目录下,与cpu架构相关的头文件在include目录下对应的子目录中。
-
init :内核初始化代码,这个目录下的代码就是linux内核启动时初始化内核的代码。
-
ipc :ipc就是 inter process commuication ,进程间通信,该目录下都是linux进程间通信的代码。
-
kernel :kernel就是Linux内核,是Linux中最核心的部分,包括进程调度、定时器等,而和平台相关的一部分代码放在arch/*/kernel目录下。
-
lib :lib是库的意思,lib目录下存放的都是一些公用的有用的库函数,注意这里的库函数和C语言的库函数不一样的,因为在内核编程中是不能用C语言标准库函数的,所以需要使用lib中的库函数,除此之外与处理器结构相关的库函数代码被放在 arch/*/lib/ 目录下。
-
mm : 目录包含了所有独立于 cpu 体系结构的内存管理代码,如页式存储管理内存的分配和释放等,而与具体硬件体系结构相关的内存管理代码位于 arch/*/mm 目录下,例如 arch/arm/mm/fault.c 。
-
net : 网络协议栈相关代码,net目录下实现各种常见的网络协议。
-
scripts :这个目录下全部是脚本文件,这些脚本文件不是linux内核工作时使用的,而是用了配置编译linux内核的。
-
security :内核安全模型相关的代码,例如最有名的SELINUX。
-
sound : ALSA、 OSS音频设备的驱动核心代码和常用设备驱动。
-
usr : 实现用于打包和压缩的cpio等。
修改内核配置
Linux内核的配置系统由三个部分组成,分别是:
-
Makefile:分布在 Linux内核源代码顶层目录及各层目录中,定义 Linux 内核的编译规则;
-
配置文件:给用户提供配置选择的功能,如Kconfig文件定义了配置项, 在编译时,使用 arch/arm64/configs/lubancat2_defconfig 文件对配置项进行赋值;
-
配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释) 和配置用户界面(linux提供基于字符界面、基于Ncurses 图形界面以及 基于 Xwindows 图形界面的用户配置界面,各自对应于make config、make menuconfig 和 make xconfig)。
make menuconfig是一个基于文本选择的配置界面, 推荐在字符终端下使用, 而这个配置文件为 lubancat2_defconfig 此时就可以看到在lubancat2_defconfig的配置选择, 可以通过键盘的”上”、”下”、”左”、”右”、”回车”、”空格”、”?”、”ESC”等按键进行选择配置,具体见:
cd kernel-6.1
make menuconfig KCONFIG_CONFIG=arch/arm64/configs/armsom_linux_rk35xx_defconfig ARCH=arm64
make savedefconfig ARCH=arm64
cp defconfig arch/arm64/configs/armsom_linux_rk35xx_defconfig
注意make menuconfig保存的配置是.config
修改完内核配置重新单独编译内核可以得到新的固件
构建内核deb包
在编译内核会生成至多5个Debian软件包,在armsom-sdk中使用以下命令构建:
./build.sh kerneldeb
生成的软件包如下:
-
linux-image-version:一般包括内核镜像和内核模块,我们还添加了设备树及设备树插件。
-
linux-headers-version:包括创建外部模块所需的头文件
-
linux-firmware-image-version:包括某些驱动程序所需的固件(这里不生成)
-
linux-image-version-dbg:在linux-image-version基础上多了debug符号
-
linux-libc-dev:包括GNU glibc之类与用户程序库相关的标头
内核deb包的更新
将生成的deb包通过USB存储设备或网络复制到运行Ubuntu或Debian镜像的板卡中,使用以下命令安装软件包:
sudo dpkg -i linux-headers-6.1.xxx-芯片型号_6.1.xxx-芯片型号-xxx_arm64.deb
sudo dpkg -i linux-image-6.1.xxx-芯片型号_6.1.xxx-芯片型号-xxx_arm64.deb
设备树编译与使用
设备树用于描述一个硬件平台的硬件资源。这个“设备树”可以被bootloader(uboot)传递到内核, 内核可以从设备树中获取硬件信息。 相当于使用定制的设备树就可以操作不一样的硬件资源, 比如i2c,spi,mipi,mini-pcie,i2s等接口,都是通过设备树去配置使能才能去正常操作它们。
设备树的编译
我们在编译kernel镜像的同时,也会编译对应的设备树。
编译生成的设备树文件和设备树源文件在同一目录下,如sige5板卡, 其设备树源文件是arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts, 编译后生成的设备树文件是arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dtb
系统的boot分区默认挂载在/boot目录下,如果我们要切换主设备树的话, 可以使用配置工具或直接修改/boot/rk-kernel.dtb软链接到的实际设备树的文件地址

如果想要自己添加设备树的话,可以按以下流程进行:
- 在kernel/arch/arm64/boot/dts/rockchip下新建一个设备树源文件,如名称为xxx.dts
- 修改同一目录下的Makefile,在 dtb-$(CONFIG_CPU_RK3576) += 后添加xxx.dtb \
- 使用./build.sh kernel命令构建内核
- 在rockdev目录下查看boot.img分区镜像文件
- 使用分区烧录工具进行烧录
设备树的使用
在RK3576/RK3588系列的板子中,每块板子都有自己的主设备树,位于 /boot/dtb 里,使用规则会在编译选项里面指定主设备树,通过软链接的方式链接到/boot/rk-kernel.dtb。
在/boot/uEnv目录下可以配置设备树插件的开启与关闭,内核的启动参数。使用ls -l /boot/uEnv 查看实际链接的配置文件

root@armsom:/boot/uEnv# cat uEnvarmsom-sige5.txt
uname_r=6.1.118-rk3576
initrd=initrd-6.1
size=0x1000000
cmdline="earlyprintk console=ttyFIQ0 console=tty1 consoleblank=0 loglevel=7 rootwait rw rootfstype=ext4"
enable_uboot_overlays=1
#overlay_start
#RS232
#dtoverlay=/dtb/overlay/armsom-rk3576-uart8-m2-overlay.dtbo
#camera
#dtoverlay=/dtb/overlay/armsom-sige5-camera-ov13850-cs0.dtbo
#dtoverlay=/dtb/overlay/armsom-sige5-camera-ov13850-cs1.dtbo
#overlay_end
cmdline是配置内核启动的参数
dtoverlay是设备树插件,#代表该设备树插件是关闭的状态,要想开启这个功能去掉#即可
部署自己的应用
我们经常有这样的需求,自己写好一个应用,想要它实现开机自启动的功能, 那么我们可以通过创建一个Systemd服务服务来实现。 下面我以创建一个简单的hello.service服务为例子,教大家如何创建自己的Systemd服务。
编写脚本
cd进入/opt目录下,使用vim编写一个hello.sh脚本
#!/bin/bash
log_file="/tmp/hello.log"
count=0
max_count=5
while [ $count -lt $max_count ]; do
echo "Hello world!" >> "$log_file"
count=$((count + 1))
if [ $count -lt $max_count ]; then
sleep 3
fi
done
该脚本实现的功能是每隔3秒就打印“Hello world!”字符串到/tmp/hello.log文件中。
赋予hello.sh可执行权限:
sudo chmod 0775 hello.sh
创建配置文件
在/etc/systemd/system/目录下创建一个hello.service配置文件,内容如下:
[Unit]
Description=Hello World Logging Service
After=network.target
[Service]
Type=simple
User=armsom
ExecStart=/opt/hello.sh
Restart=no
[Install]
WantedBy=multi-user.target
-
服务类型 (Type=simple)
这是最常见的类型,适用于 hello.sh 这种在前台运行(即会循环执行直到脚本结束)的脚本。 -
重启策略 (Restart=no)
这是为了适配你脚本“运行五次后结束”的功能而做的关键设置。通常服务会设置为 always 或 on-failure 以保持常驻,但你的脚本设计为执行特定次数后自动退出,这属于正常终止,不应该被再次重启。设置为 no 可以确保脚本完成工作后,服务状态变为 inactive (dead),这符合预期。 -
其他关键字段
-
Description:服务的描述信息,会显示在 systemctl status 命令中。
-
After:定义启动顺序,这里确保在网络就绪后再启动本服务。
-
User:建议设置为你的普通用户名,而不是 root,以提升安全性。
-
ExecStart:必须填写 hello.sh 脚本的绝对路径。
-
WantedBy=multi-user.target:表示当系统进入多用户命令行模式(即标准的非图形界面运行级别)时启用此服务
使能服务开机自启
创建或修改服务文件后,必须让 systemd 重新加载配置,使新服务生效
sudo systemctl daemon-reload
查看hello.service是否被添加到了服务列表
sudo systemctl list-unit-files --type=service | grep hello
使用以下命令将服务设置为开机自动启动
sudo systemctl enable hello.service
然后使用reboot命令重启系统, 启动系统后可以看到/tmp/hello.log下的打印

浙公网安备 33010602011771号