构建适用于RK3328芯片的Linux
本文最后更新于:2025年7月21日 晚上
前言
网上能找到适用于瑞芯微RK3328芯片的Linux系统版本都有些旧了,有些功能内核不支持,于是打算自己折腾构建最新版本的Linux系统,开启一些新的功能,顺便学习一下嵌入式开发,仅供参考。
启动流程
上图可以看出瑞芯微的芯片有2条启动流程: Boot Flow 1 / Boot Flow 2,每条流程只有loader1、loader2在构成方式上有所不同,而trust、kernel、rootfs基本一致,后续操作会对不同的地方进行单独记录,而相同的部分则放在一起。[1]
烧录地址
查阅RK3328_Linux-Debian_V1.1_Development_Guide-20170711官方手册可知,在RK3328芯片上运行Linux系统,需要将所需文件烧录到对应的地址中:
Address | Name | Path |
---|---|---|
Boot | rk3328_loader_v1.21.250.bin | |
0x00000040 | loader1 | idbloader.img |
0x00004000 | loader2 | uboot.img |
0x00006000 | atf | trust.img |
0x00008000 | boot | boot.img |
0x00040000 | rootfs | rootfs.img |
主板信息
主芯片:瑞芯微RK3288
内存颗粒:K4B2G0446C-HYH9 * 8:2GB
eMMC芯片:KLMAG1JETD-B041:16G
设备树文件:rk3328-beikeyun-1296mhz.dts form linux-6.0.y
开发环境
安装所需工具:
1 |
|
构建文件
loader1
Boot Flow 1
使用构建工具
瑞莎官方提供了适用于瑞芯微芯片的rockchip-bsp构建工具,可以很轻松方便的构建出 Boot Flow 1所需的idbloader、uboot以及trust文件,参考资料:[2] [3]
克隆构建工具
1
2
3
4
5
6
7git clone -b stable-4.4-rockpie https://github.com/radxa/rockchip-bsp.git
cd rockchip-bsp
git submodule init
git submodule update执行上述命令会拉取radxa配置的相关子模块项目,如果不想使用其中的u-boot、kernel项目(版本过于老旧),可以删掉相关目录并克隆其他仓库的源码到rockchip-bsp目录中(注意文件夹名称需保持一致,否则后续执行脚本会报错);我使用的u-boot是官方u-boot,kernel则来自unifreq:
1
2
3
4
5
6
7rm -rf u-boot kernel
git clone https://github.com/u-boot/u-boot.git
git clone https://github.com/unifreq/linux-6.1.y-rockchip.git
mv linux-6.1.y-rockchip kernel新增主板信息
修改rockchip-bsp/build/board_configs.sh文件,在适当位置新增主板配置信息:
1
2
3
4
5
6
7
8"rk3328-beikeyun")
DEFCONFIG=rockchip_linux_defconfig
UBOOT_DEFCONFIG=evb-rk3328_defconfig
DTB=rk3328-beikeyun-1296mhz.dtb
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
CHIP="rk3328"
;;▶参数含义DEFCONFIG
:kernel配置文件UBOOT_DEFCONFIG
:u-boot配置文件DTB
:设备树文件ARCH
:核心架构CROSS_COMPILE
:交叉编译工具链CHIP
:芯片型号配置BL31文件环境
下载该项目中的rk3328_bl31_v1.39.bin文件,将其放入路径:rockchip-bsp/rkbin/bin/rk33/,使用以下命令配置BL31文件环境:
1
export BL31=/home/dongxun/Desktop/rockchip-linux/radxa/rockchip-bsp/rkbin/bin/rk33/rk3328_bl31_v1.39.bin
U-Boot 需要 ARM Trusted Firmware (ATF) 的 BL31 二进制文件作为安全固件组件才能生成完整可用的启动镜像
开始构建
切换到rockchip-bsp目录执行以下命令开始构建u-boot:
1
./build/mk-uboot.sh rk3328-beikeyun
等待构建完成,会在rockchip-bsp/out/u-boot目录生成 Boot Flow 1所需的文件:
.
├── idbloader.img
├── rk3328_loader_ddr333_v1.16.250.bin
├── spi/
├── trust.img
└── uboot.img
上述通用的构建方法足矣满足正常启动Linux系统;如果想在u-boot阶段对设备完成硬件初始化以及执行更多操作,就需要使用对应的设备树构建u-boot,属于高级功能。
该方法在最新的u-boot项目中构建未成功…
将rk3328-beikeyun-1296mhz.dts文件开头的 #include "rk3328.dtsi
“ 改为 #include "rk3328-u-boot.dtsi"
后放入路径:u-boot/arch/arm/dts中,然后修改该目录下的MakeFile,在适当位置新增以下内容:
1 |
|
执行以下命令加载RK3328默认配置文件到 .config,并查询默认设备树名称在该文件中哪几个行出现过:
1 |
|
212:CONFIG_DEFAULT_DEVICE_TREE=”rockchip/rk3328-evb”
554:CONFIG_DEFAULT_FDT_FILE=”rockchip/rk3328-evb.dtb”
1112:CONFIG_OF_LIST=”rockchip/rk3328-evb”
1116:CONFIG_SPL_OF_LIST=”rockchip/rk3328-evb”
将上述查询结果中出现rk3328-evb的地方名称改为当前主板的设备树名称:
212:CONFIG_DEFAULT_DEVICE_TREE=”rockchip/rk3328-beikeyun-1296mhz”
554:CONFIG_DEFAULT_FDT_FILE=”rockchip/rk3328-beikeyun-1296mhz.dtb”
1112:CONFIG_OF_LIST=”rockchip/rk3328-beikeyun-1296mhz”
1116:CONFIG_SPL_OF_LIST=”rockchip/rk3328-beikeyun-1296mhz”
将rk3328-beikeyun-1296mhz.dts文件放入以下路径:u-boot/dts/upstream/src/arm64/rockchip,然后保存当前配置到defconfig,并复制到u-boot/configs文件夹中重命名:
1 |
|
修改build/board_configs.sh文件,修改主板信息的UBOOT配置文件名:
1 |
|
切换到rockchip-bsp目录,执行以下命令开始构建u-boot:
1 |
|
单独构建文件
单独构建各文件使用的源码大部分均来自瑞芯微官方Github仓库:rockchip-linux,只有u-boot源码来自radxa,因为官方u-boot构建时会有各种报错,而且无法生成u-boot-tpl.bin文件,暂不清楚具体原因。[1]
loader1 - idbloader.img(miniloader)
idbloader.img(miniloader) 由2个文件组成:ddr.bin + miniloader.bin,均由瑞芯微官方提供,而这2个文件都保存在rkbin仓库中,首先将仓库克隆到本地:
1 |
|
对于RK3328而言,在rkbin/bin/rk33目录中没有提供rk3328_miniloader_vx.xx.bin文件,不过我发现了一个Github仓库:uboot_builder,里面有适用于RK3328芯片的miniloader文件(本次操作暂未使用)。
通过查看rkbin/RKBOOT/RK3328MINIALL.ini配置信息得知可使用:rk322xh_miniloader_v2.50.bin,路径如下:rkbin/bin/rk33/rk322xh_miniloader_v2.50.bin,在rkbin根目录执行以下命令:
1 |
|
-n
==> set image name to ‘name’ :指定镜像名称,一般是芯片型号或者主板型号-T
==> set image type to ‘type’ :指定镜像类型,可以输入tools/mkimage -T list查看更多类型,这里使用的类型为:rksd : Rockchip SD Boot Image-d
==> use image data from ‘datafile’ :使用的二进制数据文件,这里使用对应芯片的rkxx_ddr_vx.xx.bin二进制文件rkxx_miniloader_vx.xx.bin
:对应芯片miniloader二进制文件
烧录地址:Address:0x00000040
,Name:loader1
。
loader1 - idbloader.img(TPL/SPL)
idbloader.img(TPL/SPL) 由2个文件组成:u-boot-tpl.bin + u-boot-spl.bin,在构建u-boot项目时会自动生成,也可以使用以下操作进行手动生成。
进入u-boot目录,执行以下命令开始配置u-boot然后开始构建:
1 |
|
等待构建完成,会在u-boot根目录下生成以u-boot
名称开头的一系列文件,以及2个核心文件:spl/u-boot-spl.bin
、tpl/u-boot-tpl.bin
。
执行以下命令即可得到idbloader.img(TPL/SPL):
1 |
|
-n
==> set image name to ‘name’ :指定镜像名称,一般是芯片型号或者主板型号-T
==> set image type to ‘type’ :指定镜像类型,可以输入tools/mkimage -T list查看更多类型,这里使用的类型为:rksd : Rockchip SD Boot Image-d
==> use image data from ‘datafile’ :使用的二进制数据文件,这里使用u-boot构建生成的u-boot-tpl.bin二进制文件u-boot-spl.bin.bin
:这里使用u-boot构建生成的u-boot-spl.bin二进制文件
烧录地址:Address:0x00000040
,Name:loader1
。
loader2
Boot Flow 2
单独构建文件
loader2 - uboot.img
uboot.img 需要使用u-boot和rkbin两个项目的文件,先克隆u-boot仓库,然后将rkbin仓库的文件全部复制到u-boot中:
1 |
|
需要修改scripts/dtc/dtc-lexer.l文件,将YYLTYPE yylloc;
改为extern YYLTYPE yylloc;
,否则后续构建会报错:multiple definition of `yylloc’
在u-boot项目中,已经包含各种芯片的u-boot示例配置文件,存放路径为:u-boot/configs/,对于RK3328,使用以下命令加载默认配置并开始构建:
1 |
|
等待构建完成,会在根目录下生成以u-boot
名称开头的一系列文件,对于Boot Flow 1,还需将生成的u-boot.bin转换成miniloader可识别文件uboot.img才能烧录到主板,执行以下命令即可:
1 |
|
烧录地址:Address:0x00004000
,Name:loader2
。
loader2 - u-boot.itb
u-boot.itb 由bl31.elf, u-boot-nodtb.bin, u-boot.dtb文件组成,第一个文件可以下载该项目中的rk3328/rk3328_bl31_v1.42.elf文件,后2个文件均是u-boot项目构建时生成的,将这3个文件放入u-boot根目录,执行以下命令开始构建:
1 |
|
烧录地址:Address:0x00004000
,Name:loader2
。
trust
进入rkbin目录,使用以下命令,通过rkbin/RKTRUSRT/目录中对应芯片的配置文件来生成trust.img:
1 |
|
烧录地址:Address:0x00006000
,Name:atf
。
kernel
瑞芯微kernel
首先克隆官方kernel源码:[4]
1 |
|
使用以下命令查看当前项目是否为develop-6.1
分支,默认为develop-4.4
分支,后续构建时会报错,暂不清楚具体原因;
1 |
|
在kernel项目中,已经包含各芯片的kernel示例配置文件,稍作修改即可进行使用,对于RK3328而言,其芯片架构为arm64,对应的示例配置文件路径为:kernel/arch/arm64/configs,但是该路径下没有RK3328专属的示例配置文件,所以使用以下命令加载通用配置到 .config文件:
1 |
|
将rk3328-beikeyun-1296mhz.dts放入以下路径:kernel/arch/arm64/boot/dts/rockchip,然后修改该目录下的MakeFile,在适当位置新增一行填入以下内容:
1 |
|
切换到kernel根目录,开始编译官方kernel文件:
1 |
|
等待编译完成,会生成以下文件:
OBJCOPY arch/arm64/boot/Image
GZIP arch/arm64/boot/Image.gz
对于32位架构的核心,编译时会生成zImage文件
对于64位架构的核心,编译会生成Image文件
根据对应设备树编译boot.img文件:
1 |
|
等待编译完成,会生成以下文件:
Image: resource.img (with rk3328-beikeyun-1296mhz.dtb logo.bmp logo_kernel.bmp) is ready
Image: boot.img (with Image resource.img) is ready
Image: zboot.img (with Image.lz4 resource.img) is ready
生成的上述文件都是独立存在的,无法烧录到主板,还需要根据设备树二进制文件以及extlinux.conf文件打包成boot.img才行,依次执行以下命令:
1 |
|
extlinux.conf文件需要根据对应芯片进行修改:设备树文件名、调试UART的基地址、主板的根分区等信息,否则可能无法正常启动。[5]
经过上述操作,boot.img文件才可以烧录到主板的kernel分区。
烧录地址:Address:0x00008000
,Name:boot
。
最新版kernel
使用构建工具
请先完成本文章目录:构建文件 -> loader1 -> Boot Flow 1 -> 使用构建工具 的相关操作及配置。
首先需要配置kernel中用到的设备树文件,将rk3328-beikeyun-1296mhz.dts文件放入以下路径:kernel/arch/arm64/boot/dts/rockchip,然后修改该目录下的MakeFile,在适当位置新增以下内容:
1 |
|
切换到rockchip-bsp根目录,使用以下命令开始构建kernel:
1 |
|
等待构建完成,会在rockchip-bsp/out/kernel目录生成所需的文件:
.
├── boot.img
├── kernel
│ ├── Image
│ └── rk3328-beikeyun-1296mhz.dtb
烧录地址:Address:0x00008000
,Name:boot
。
单独构建Kernel
本次构建使用官方Linux Kernel:The Linux Kernel Archives。
⚠官方最新内核不一定适配当前芯片,甚至可能造成不兼容等后果,请慎重操作!
下载Linux 6.15.5内核源码并解压:
1 |
|
在Linux官方内核中,并不包含瑞芯微芯片的配置文件,需要使用以下命令从瑞芯微官方kernel中复制一份通用配置文件到最新的Linux内核中:
1 |
|
还需配置设备树文件,先将rk3328.dtsi文件下载下来,和rk3328-beikeyun-1296mhz.dts文件一起放入以下路径:linux-6.15.5/arch/arm64/boot/dts/rockchip/,然后修改该目录下的MakeFile,在适当位置新增以下内容:
如果不使用unifreq仓库的rk3328.dtsi文件,后续构建会报错。
1 |
|
进入linux-6.15.5目录,使用以下命令配置构建环境:
1 |
|
使用以下命令加载通用配置到 .config文件:
1 |
|
根据需求修改默认配置并保存退出,然后开始构建kernel:
1 |
|
等待构建完成,可看到以下信息,其中Image就是需要的文件,但是还需要进一步处理才能生成boot.img。
SORTTAB vmlinux
OBJCOPY arch/arm64/boot/Image
GZIP arch/arm64/boot/Image.gz
切换到kernel上一级目录新建一个3328文件夹,使用以下命令打包kernel-dtb文件:
1 |
|
克隆rockchip-mkbootimg项目并编译相关工具:
1 |
|
在3328目录执行以下命令生成boot.img:
1 |
|
烧录地址:Address:0x00008000
,Name:boot
。
rootfs
一般简称根文件系统。
使用现有rootfs
可查看校园网联合镜像站,清华大学开源软件镜像站获取更多系统镜像源码文件,以下只列出部分Linux镜像源码下载地址:
Armbian:Index of /apt/dists/
Debian:Image server for Incus and LXC
Ubuntu:Index of /ubuntu-base/releases
需要根据芯片架构选择合适的版本
配置根文件系统:[6]
安装qemu
1
sudo apt-get install qemu-user-static
创建临时文件夹并将下载的镜像源码文件解压到其中
1
2
3
4
5
6
7mkdir temp
# 如果是Ubuntu系统使用以下命令:
sudo tar -zxvf ubuntu-base-22.04-base-arm64.tar.gz -C temp
# 如果是Debian系统使用以下命令:
sudo tar -xvf rootfs.tar.xz -C temp准备网络工作
1
sudo cp -b /etc/resolv.conf temp/etc/resolv.conf
准备qemu
1
sudo cp /usr/bin/qemu-aarch64-static temp/usr/bin/
挂载主机/dev
1
sudo mount --bind /dev /home/dongxun/Desktop/temp/dev
如果不执行该操作,后续apt update会有报错:/usr/bin/apt-key: 95: cannot create /dev/null: Permission denied
进入根文件系统
1
sudo chroot temp
更换软件源
系统源地址默认为官方源,在国内更新、下载时很不方便,使用
vi
工具编辑/etc/apt/sources.list
,将其更换为清华源:1
2
3
4
5
6
7
8
9
10
11deb http://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware
# deb-src http://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware
deb http://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware
# deb-src http://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware
deb http://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware
# deb-src http://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware
deb http://mirrors.tuna.tsinghua.edu.cn/debian-security bookworm-security main contrib non-free non-free-firmware
# deb-src http://mirrors.tuna.tsinghua.edu.cn/debian-security bookworm-security main contrib non-free non-free-firmware这里强制使用HTTP,而不是官方推荐的HTTPS,是因为使用HTTPS更新时会有CA证书报错:Certificate verification failed
后续正常进入系统,请更换为HTTPS即可更新软件包
1
2
3apt update
apt upgrade安装所需工具
1
apt install -y usbutils fdisk man-db sudo nano openssh-server net-tools network-manager iputils-ping bash-completion kmod initramfs-tools linux-base netplan.io git systemd-timesyncd apt-utils dialog vim ifupdown ethtool wireless-tools udev htop rsyslog lsb-release cloud-guest-utils parted toilet figlet lolcat
开启ssh远程访问
1
2
3sed -i '/PasswordAuthentication /c PasswordAuthentication yes' /etc/ssh/ssh_config
sed -i '/PermitRootLogin /c PermitRootLogin yes' /etc/ssh/sshd_config添加用户并设置密码
1
2
3useradd -s '/bin/bash' -m -G adm,sudo username
passwd username给root用户设置密码
1
passwd root
修改主机名
1
2
3
4
5# Ubuntu
echo "ubuntu" > /etc/hostname
# Debian
echo "debian" > /etc/hostname退出根文件系统
1
exit
安装内核模块
此操作需要在kernel目录下执行,会将构建的.ko文件复制到根文件系统中。
1
sudo make INSTALL_MOD_PATH=~/Desktop/temp modules_install
制作根文件系统镜像:
创建根文件系统目录
1
mkdir rootfs
查看temp文件夹大小
1
sudo du -sh temp/
创建一个linuxroot.img文件
1
dd if=/dev/zero of=linuxroot.img bs=1M count=1024
count需要根据步骤2中查询到的temp文件夹大小增加20%后填入其数值
格式化文件格式
1
mkfs.ext4 linuxroot.img
将文件挂在到目录
1
sudo mount linuxroot.img rootfs/
复制根文件系统
1
sudo cp -rfp temp/* rootfs/
取消挂载目录
1
2
3sudo umount rootfs/
sudo umount /home/dongxun/Desktop/temp/dev此操作会删除rootfs文件夹内的所有文件,但相关文件已经保存到了linuxroot.img中
检查文件系统
1
e2fsck -p -f linuxroot.img
调整镜像到最小尺寸
1
resize2fs -M linuxroot.img
将linuxroot.img拷贝到radxa工具的rootfs目录中,并修改文件名为:linaro-rootfs.img
1
cp linuxroot.img ~/Desktop/rockchip-linux/radxa/rockchip-bsp/rootfs/linaro-rootfs.img
切换到rockchip-bsp目录,开始生成可以烧录的system.img
1
./build/mk-image.sh -c rk3328 -t system -r rootfs/linaro-rootfs.img
烧录地址:Address:0x00000000
,Name:system
。
手动构建rootfs
使用Buildroot项目进行构建。
首先下载Buildroot源码:
1 |
|
解压源码:
1 |
|
后续有需求再补充…
烧录地址:Address:0x00040000
,Name:rootfs
。
适配驱动
USB无线网卡
MT7601U
官方Linux Kernel中已经包含了该芯片的驱动源码,使用make menuconfig
打开配置菜单页面,在 Device Drivers > Network device support > Wireless LAN 下就能找到 MediaTek MT7601U (USB) support,开启后重新构建内核(重新烧录内核)或者单独编译驱动(手动加载驱动)即可正常使用。
RTL8192CU
官方Linux Kernel中已经包含了该芯片的驱动源码,使用make menuconfig
打开配置菜单页面,在 Device Drivers > Network device support > Wireless LAN > Realtek rtlwifi family of devices 下就能找到 Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter,开启后重新构建内核(重新烧录内核)或者单独编译驱动(手动加载驱动)即可正常使用。
SDIO无线网卡
RTL8189ETV
官方Linux Kernel中目前没有适配该芯片的驱动,可以使用rtl8189ES_linux仓库提供的驱动源码自行编译。[7]
先将仓库克隆到kernel/drivers/net/wireless/realtek中并重命名:
1 |
|
编辑该目录下的Kconfig,在适当位置新增以下内容:
1 |
|
编辑该目录下的Makefile,在适当位置新增以下内容:
1 |
|
进入rtl8189es目录,编辑Kconfig,改为以下格式:
1 |
|
切换到kernel根目录,使用make menuconfig
打开配置菜单页面,在 Device Drivers > Network device support > Wireless LAN 下就能找到 Realtek 8189E SDIO WIFI,开启后重新构建内核(重新烧录内核)或者单独编译驱动(手动加载驱动)即可正常使用。
eMMC扩容
对于自己构建的Linux系统,烧录到板载eMMC芯片后上电启动,一般情况下系统分区是未完全占满eMMC的所有磁盘空间,需要根据以下操作对磁盘进行扩容。
查看磁盘存储情况:
1 |
|
1 |
|
查看当前系统分区磁盘信息:
1 |
|
1 |
|
3180510(系统结束扇区) ≠ 30535679(eMMC扇区总数)
修复GPT表错误(关键步骤):
1 |
|
扩展分区到最大空间后进行重启:
1 |
|
扩展文件系统:
1 |
|
再次查询磁盘情况:
1 |
|
1 |
|
美化Linux
登录时打印字符
新建文件:
1 |
|
填入以下内容:
1 |
|
修改文件权限:
1 |
|
测试功能:
1 |
|
登录时打印系统信息
新建文件:
1 |
|
填入以下内容:
1 |
|
修改文件权限:
1 |
|
测试功能:
1 |
|