RK3566 开发环境与镜像构建
说明
- 本页记录
RK3566平台在 Ubuntu 环境下准备工具链, 编译u-boot与 Linux 内核, 制作启动镜像的流程. - 适合作为 Rockchip 平台开发环境初始化与镜像构建的实践记录.
- 本页中出现的 master 是经核对后仍存在的上游仓库分支名, 不是本仓库默认分支的建议.
sudo apt install device-tree-compiler git vim genext2fs
安装 python2
使用 pyenv 安装并管理 python
目的是 不污染系统环境, 只需要 删除某个目录就可以卸载所有 python 环境
## 自动安装 pyenv 环境
curl https://pyenv.run | bash
## 执行后, 手动添加到 ~/.bashrc, 并执行
export PYENV_ROOT="$HOME/.pyenv"
command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
安装 python2 最新版
pyenv install 2.7.18
使用
pyenv global 2.7.18
下载
准备目录
mkdir ~/develop && cd ~/develop
下载 u-boot 源码
git clone https://github.com/rockchip-linux/u-boot.git -b next-dev
下载 rkbin 到 u-boot 同级目录
git clone https://github.com/rockchip-linux/rkbin.git
下载 linux 内核 源码
git clone https://github.com/rockchip-linux/kernel.git -b develop-5.10
下载 编译环境 (Firmware and Tool Binarys)
mkdir -p prebuilts/gcc && cd prebuilts/gcc
git clone https://github.com/rockchip-toybrick/linux-x86.git
编译
编译 uboot
cd ~/develop/u-boot
./make.sh rk3566
会在当前路径下生成 uboot.img 和 rk356x_spl_loader_v1.18.112.bin 文件
编译 linux 源码
cd ~/develop
git clone https://github.com/rockchip-linux/kernel.git -b develop-5.10
cd ~/develop/kernel
make ARCH=arm64 CROSS_COMPILE=../prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- rockchip_linux_defconfig
# 生成 vmlinux 和 arch/arm64/boot/Image
make ARCH=arm64 CROSS_COMPILE=../prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- -j8 Image
# 生成设备树 arch/arm64/boot/dts/rockchip/rk3566-box-demo-v10.dtb
make ARCH=arm64 CROSS_COMPILE=../prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- -j8 dtbs
ls -alh arch/arm64/boot/dts/rockchip/rk3566-*
制作镜像文件
mkdir boot
cp arch/arm64/boot/Image boot/
cp arch/arm64/boot/dts/rockchip/rk3566-box-demo-v10.dtb boot/
mkdir boot/extlinux vi boot/extlinux/extlinux.conf
label rockchip-kernel-5.10
kernel /Image
fdt /rk3566.dtb
append earlycon=uart8250,mmio32,0xff1a0000 root=PARTUUID=B921B045-1D rootwait rootfstype=ext4 init=/sbin/init
genext2fs -b 40960 -B $((1024)) -d boot/ -i 8192 -U boot_rk3566.img
生成的文件: boot_rk3566.img
烧写工具
https://doc.embedfire.com/linux/rk356x/quick_start/zh/latest/quick_start/flash_img/flash_img.html
1.2.1.1. 工具获取 镜像的烧录需要使用到烧录工具 RKDevTool 和驱动程序 DriverAssitant
分析 uboot
u-boot/include/configs/
evb_rk3568.h rk3568_common.h rockchip-common.h
定义了一些配置, 如: 分区, 可参考
// 如果 tftp 和 bootm, 未定义加载地址, 则默认使用该地址
#define CONFIG_SYS_LOAD_ADDR 0x00c00800
# 从tftp下载uImage镜像到 CONFIG_SYS_LOAD_ADDR 这个地址上, 并从该地址处 加载 并运行.
tftp uImage; bootm
uboot 的 bootm 命令
用于把内核加载到指定地址处运行
测试 img 镜像
Orangepi3b_1.0.2_ubuntu_focal_server_linux5.10.160.img
sudo fdisk -lu Orangepi3b_1.0.2_ubuntu_focal_server_linux5.10.160.img
可以看到有两个分区.

# 挂载分区
sudo mkdir -p /mnt/boot /mnt/linux
# 起始扇区: 61440, 每个扇区 512 bytes
sudo mount -o loop,offset=$((61440*512)) Orangepi3b_1.0.2_ubuntu_focal_server_linux5.10.160.img /mnt/boot
# sudo umount /mnt/boot
# 起始扇区: 2158592, 每个扇区 512 bytes
sudo mount -o loop,offset=$((2158592*512)) Orangepi3b_1.0.2_ubuntu_focal_server_linux5.10.160.img /mnt/linux
# sudo umount /mnt/linux


使用 orangepi-build 编译
下载 orangepi-build
mkdir ~/develop && cd ~/develop
git clone https://github.com/orangepi-xunlong/orangepi-build.git -b next
cd orangepi-build
忽略修改被覆盖
vim userpatches/config-default.conf
IGNORE_UPDATES=“yes”
编译
连续执行 sudo ./build.sh 分别编译 U-boot / Kernel
重新编译
uboot
git clone https://github.com/rockchip-linux/u-boot.git -b next-dev
编译工具
git clone https://github.com/rockchip-linux/rkbin.git
git clone https://github.com/rockchip-toybrick/linux-x86.git -b master
注: 这里的 master 是 rockchip-toybrick/linux-x86 当前仍在使用的上游分支名. 执行前仍建议先确认 tag 和分支状态.
安装基本依赖
sudo apt-get install build-essential libncurses-dev bison flex libssl-dev libelf-dev genext2fs vim git tree
ubuntu 22.04 交叉编译工具
wget https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/_toolchain/gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu.tar.xz
tar -xvf gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu.tar.xz
linux 6.5.8 源码
wget https://mirrors.tuna.tsinghua.edu.cn/kernel/v6.x/linux-6.5.8.tar.xz
# 加压到了 linux-6.5.8 目录
tar -xvf linux-6.5.8.tar.xz
# 编译
cd linux-6.5.8
# 定制的 ./arch/arm64/configs/rockchip_linux_defconfig
export ARCH=arm64
export CROSS_COMPILE=../gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-
make rockchip_linux_defconfig
# 生成文件: vmlinux 和 arch/arm64/boot/Image
make -j$(nproc) Image
#
make -j$(nproc) dtbs
mkdir boot
cp arch/arm64/boot/dts/rockchip/rk3566-box-demo.dtb boot/
cp arch/arm64/boot/Image boot/
mkdir boot/extlinux
vi boot/extlinux/extlinux.conf
label rockchip-kernel-6.5.8
kernel /Image
fdt /rk3566.dtb
append earlycon=uart8250,mmio32,0xfe660000 root=PARTUUID=B921B045-1D rw rootwait rootfstype=ext4 init=/sbin/init
genext2fs -b 40960 -B 1024 -d boot/ -i 8192 -U boot_rk3566.img
使用 busybox 制作根文件系统
参考: https://www.cnblogs.com/zyly/p/17438770.html
wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2
tar -xvf busybox-1.36.1.tar.bz2
cd busybox-1.36.1
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
# 使用默认配置
make defconfig
make menuconfig
# 使用 动态编译
Settings --->
-- Build Options
[ ] Build static binary (no shared libs)
[*] Build Shared libbusybox
make -j$(nproc)
# 根文件系统将输出在 rootfs 目录下
make install CONFIG_PREFIX=rootfs
这里的 rootfs 是这样的:
imxood@vm-imxood-pc:~/develop/busybox-1.36.1$ tree -L 1 rootfs/
rootfs/
├── bin
├── lib64
├── linuxrc
├── sbin
└── usr
这些文件不足以构成根文件系统, 需要进行完善.
添加库文件
cd rootfs mkdir -p lib ./usr/lib/ ./usr/lib64/
cp -a ../../gcc-arm-11.2-2022.02-x8664-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/lib/_so ./lib cp -a ../../gcc-arm-11.2-2022.02-x8664-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/lib64/_so ./lib64/ cp -a ../../gcc-arm-11.2-2022.02-x8664-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/usr/lib/_so ./usr/lib/ cp -a ../../gcc-arm-11.2-2022.02-x8664-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/usr/lib64/_so ./usr/lib64/
构建 etc 目录
mkdir etc
# 使用 busybox 的默认配置
cp -a ../examples/bootfloppy/etc/* ./etc/
修改 etc/inittab
这个文件是 init 进程解析的配置文件, 通过这个配置文件决定执行哪个进程, 何时执行
# 系统启动时
::sysinit:/etc/init.d/rcS
# 系统启动按下Enter键时
::askfirst:-/bin/sh
# 按下Ctrl+Alt+Del键时
::ctrlaltdel:/sbin/reboot
# 系统关机时
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
# 系统重启时
::restart:/sbin/init
以上内容定义了系统启动时, 关机时, 重启时, 按下 Ctrl+Alt+Del 键时执行的进程
修改 etc/init.d/rcS 文件
#!/bin/sh
# 挂载 /etc/fstab 中定义的所有文件系统
/bin/mount -a
# 挂载虚拟的 devpts 文件系统 用于用于伪终端设备
/bin/mkdir -p /dev/pts
/bin/mount -t devpts devpts /dev/pts
# 使用 mdev 动态管理u盘和鼠标等热插拔设备
/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug
# 扫描并创建节点
/sbin/mdev -s
修改 init.d 文件权限: chmod -R 777 etc/init.d/*
修改 etc/fstab
etc/fstab 存放的是文件系统信息. 在系统启动后执行 /etc/init.d/rcS 中的 /bin/mount -a 命令时, 自动挂载这些文件系统
# <file system> <mount point> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
这里我们挂载的文件系统有三个 proc sysfs 和 tmpfs, 在内核中 proc 和 sysfs 默认都支持, 而 tmpfs 是没有支持的, 我们需要添加 tmpfs 的支持
修改 etc/profile
etc/profile 的作用是设置环境变量, 每个用户登录时都会运行它, 将文件内容修改为:
# 主机名
export HOSTNAME=zy
# 用户名
export USER=root
# 用户目录
export HOME=/root
# 终端默认提示符
export PS1="[$USER@$HOSTNAME:\$PWD]\# "
# 环境变量
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
# 动态库路径
export LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
构建 dev 目录
在 rootfs 目录, 创建 dev 文件夹:
mkdir dev
sudo mknod dev/console c 5 1 sudo mknod dev/null c 1 3
构建其他文件
mkdir mnt proc tmp sys root
tree -L 1
.
├── bin
├── dev
├── etc
├── lib
├── lib64
├── linuxrc
├── mnt
├── proc
├── root
├── sbin
├── sys
├── tmp
└── usr
制作 ext4 根文件系统 镜像
cd ~/develop/busybox-1.36.1
mkdir busybox_rootfs
# 创建 300M 的空镜像文件, 具体大小 视情况而定
dd if=/dev/zero of=busybox_ext4_rootfs.img bs=1M count=300
# 格式化为 ext4
mkfs.ext4 busybox_ext4_rootfs.img
sudo mount busybox_ext4_rootfs.img busybox_rootfs
sudo cp -af ./rootfs/* ./busybox_rootfs/
sudo umount busybox_rootfs
rm busybox_rootfs -rf
用 e2fsck 修复及检测镜像文件系统, resize2fs 减小镜像文件的大小
imxood@vm-imxood-pc:~/develop/busybox-1.36.1$ e2fsck -p -f busybox_ext4_rootfs.img
busybox_ext4_rootfs.img: 506/76800 files (0.2% non-contiguous), 26813/76800 blocks
imxood@vm-imxood-pc:~/develop/busybox-1.36.1$ resize2fs -M busybox_ext4_rootfs.img
resize2fs 1.46.5 (30-Dec-2021)
Resizing the filesystem on busybox_ext4_rootfs.img to 26912 (4k) blocks.
The filesystem on busybox_ext4_rootfs.img is now 26912 (4k) blocks long.
imxood@vm-imxood-pc:~/develop/busybox-1.36.1$ ls -alh busybox_ext4_rootfs.img
-rw-rw-r-- 1 imxood imxood 106M 10月 24 01:51 busybox_ext4_rootfs.img
最后得到 104MB 的 busybox_ext4_rootfs.img 镜像文件
使用 Ubuntu base 构建 rootfs
参考: https://www.cnblogs.com/zyly/p/17442055.html
下载 ubuntu-base 23.10
wget https://repo.huaweicloud.com/ubuntu-cdimage/ubuntu-base/releases/23.10/release/ubuntu-base-23.10-base-arm64.tar.gz
# 创建多级目录
mkdir -p rootfs/ubuntu
解压后的文件, 需要保留 ubuntu-base 中的文件权限及所有者, 解压时需要 root 权限或者 sudo 操作, 且使用-p 参数保留权限
sudo tar -xpvf ubuntu-base-23.10-base-arm64.tar.gz -C rootfs/ubuntu/
cd rootfs
安装 qemu
qemu-user-static 是一个仿真器, 可以选取 arm64 配置文件仿真开发板运行环境, 然后挂载下载的 ubuntu-base 文件, 从而构建 ubuntu 文件系统
sudo apt-get install qemu-user-static
由于下载的 ubuntu-base 是 aarch64 架构的, 因此需要拷贝 qemu-aarch64-static 到 ubuntu/usr/bin/ 下
sudo cp /usr/bin/qemu-aarch64-static ubuntu/usr/bin/
设置 ubuntu23 的软件源
sudo vim ubuntu/etc/apt/sources.list
deb http://mirrors.huaweicloud.com/ubuntu-ports/ mantic main multiverse restricted universe
deb http://mirrors.huaweicloud.com/ubuntu-ports/ mantic-backports main multiverse restricted universe
deb http://mirrors.huaweicloud.com/ubuntu-ports/ mantic-proposed main multiverse restricted universe
deb http://mirrors.huaweicloud.com/ubuntu-ports/ mantic-security main multiverse restricted universe
deb http://mirrors.huaweicloud.com/ubuntu-ports/ mantic-updates main multiverse restricted universe
deb-src http://mirrors.huaweicloud.com/ubuntu-ports/ mantic main multiverse restricted universe
deb-src http://mirrors.huaweicloud.com/ubuntu-ports/ mantic-backports main multiverse restricted universe
deb-src http://mirrors.huaweicloud.com/ubuntu-ports/ mantic-proposed main multiverse restricted universe
deb-src http://mirrors.huaweicloud.com/ubuntu-ports/ mantic-security main multiverse restricted universe
deb-src http://mirrors.huaweicloud.com/ubuntu-ports/ mantic-updates main multiverse restricted universe
设置 DNS
为了可以联网更新软件, 我们拷贝本机的 dns 配置文件到根文件系统
sudo cp /etc/resolv.conf ubuntu/etc/resolv.conf
然后在/etc/resolv.conf 文件中添加 dns:
sudo vim ubuntu/etc/resolv.conf
nameserver 8.8.8.8
nameserver 114.114.114.114
挂载/卸载 ubuntu-base 文件系统
在 rootfs 目录下创建挂载脚本 mnt_ubuntu.sh
sudo vim mnt_ubuntu.sh
#!/bin/bash
mnt() {
echo "MOUNTING"
sudo mount -t proc /proc ${2}proc
sudo mount -t sysfs /sys ${2}sys
sudo mount -o bind /dev ${2}dev
sudo mount -o bind /dev/pts ${2}dev/pts
sudo chroot ${2}
}
umnt() {
echo "UNMOUNTING"
sudo umount ${2}proc
sudo umount ${2}sys
sudo umount ${2}dev/pts
sudo umount ${2}dev
}
if [ "$1" == "-m" ] && [ -n "$2" ] ;
then
mnt $1 $2
elif [ "$1" == "-u" ] && [ -n "$2" ];
then
umnt $1 $2
else
echo ""
echo "Either 1'st, 2'nd or both parameters were missing"
echo ""
echo "1'st parameter can be one of these: -m(mount) OR -u(umount)"
echo "2'nd parameter is the full path of rootfs directory(with trailing '/')"
echo ""
echo "For example: ch-mount -m /media/sdcard/"
echo ""
echo 1st parameter : ${1}
echo 2nd parameter : ${2}
fi
给脚本执行权限
sudo chmod +x mnt_ubuntu.sh
挂载 ubuntu-base 文件系统
mnt_ubuntu.sh -m ubuntu/
更新软件包仓库, 安装一些工具
apt update
apt install net-tools ethtool ifupdown psmisc nfs-common htop vim rsyslog iputils-ping language-pack-en-base sudo network-manager systemd openssh-sftp-server
安装桌面环境
# 需要3个G?
apt install xubuntu-desktop
sudo add-apt-repository multiverse
# (可选的安装一些软件包, 如 媒体播放器?)
sudo apt install xubuntu-restricted-extras
系统设置
修改密码
passwd root
设置主机名称和IP
echo "rk3566" > /etc/hostname
echo "127.0.0.1 localhost" >> /etc/hosts
echo "127.0.0.1 rk3566" >> /etc/hosts
配置DHCP
配置了网络DHCP, 这样系统启动以后就会自动设置好网络.
网卡eth0:
echo auto eth0 > /etc/network/interfaces.d/eth0
echo iface eth0 inet dhcp >> /etc/network/interfaces.d/eth0
无线网卡wlan:
echo auto wlan0 > /etc/network/interfaces.d/wlan0
echo allow-hotplug wlan0 >> /etc/network/interfaces.d/wlan0
echo iface wlan0 inet dhcp >> /etc/network/interfaces.d/wlan0
在实际测试中网口必须接入网线系统才能正常启动, 就是在不联网的情况下, 每次开机都要等待很久, 卡在网络连接上5分钟, 这里我们可以修改下面这个文件:
vim /lib/systemd/system/networking.service
TimeoutStartSec=2sec
修改系统重启 默认等待时间
重启开发板的时候, 如果有进程没有结束, 系统就会等待, 默认等待时间很长, 导致重启速度慢.
我们可以修改默认等待时间:
vim /etc/systemd/system.conf
#DefaultTimeoutStartSec=90s
DefaultTimeoutStopSec=2s
#DefaultTRestartSec=100ms
卸载文件系统
exit
./mnt_ubuntu.sh -u ubuntu/
制作根文件系统镜像
创建空镜像文件
dd if=/dev/zero of=ubuntu_ext4_rootfs.img bs=1M count=6144
mkfs.ext4 ubuntu_ext4_rootfs.img
挂载镜像文件到 ubuntu_rootfs
mkdir ubuntu_rootfs
sudo mount ubuntu_ext4_rootfs.img ubuntu_rootfs
将ubuntu的文件复制到该空文件夹中
sudo cp -af ./ubuntu/* ./ubuntu_rootfs/
卸载
umount ubuntu_rootfs
ls -alh ubuntu_ext4_rootfs.img
rw-rw-r-- 1 imxood imxood 6.0G 10月 25 00:40 ubuntu_ext4_rootfs.img
此时就得到了 ext4 根文件系统镜像 ubuntu_ext4_rootfs.img
用 e2fsck 修复及检测镜像文件系统, resize2fs 减小镜像文件的大小
e2fsck -p -f ubuntu_ext4_rootfs.img
resize2fs -M ubuntu_ext4_rootfs.img
du -sh ubuntu_ext4_rootfs.img
3.9G ubuntu_ext4_rootfs.img
/home/imxood/develop/rootfs/ubuntu_ext4_rootfs.img