RK3568跑Ubuntu 24.04全路程指南(以正点原子的RK3568开发板为例子)
前言
终于想起来自己的老本行嵌入式了,最近的话,有些断更主要是在疯狂的梭哈SDK的配置。下面我们就来简单的说一说,如何在RK3568上跑Ubuntu24.04
PS: 有人问过我说会不会不稳定,其实,Ubuntu主要看桌面,X11的话依托底下的硬件驱动,硬件驱动稳定那就不怕,只要是厂商产出的。自己搞的开源硬件驱动另谈;Wayland我没成功过,总是0帧起手爆炸,查半天也不知道为什么就SegFault了。
下面,就让我们在Ubuntu24.04上,配置一下如何在RK3568上跑Ubuntu24.04。
厂商SDK的编译(这个看各自咋操作)
以正点原子为例子,SDK是魔改的RK-SDK的。所以如果你的板子的厂商也是魔改,那太好办了。我们的基本的原理就是------替换打包的Rootfs下的ext2,直接调用内部的updateimg生成update.img文件就好。这里,笔者发现正点原子的Doc里没有对编译Linux5.10的说明,笔者这里单独补充一下。
使用Linux 4.19版本的朋友需要注意
高版本的Ubuntu24.04早就不支持直接下Python2了,啥年代还在用Python2呢?可惜,这个版本的SDK强依赖Python2,笔者之前用默认的Python3编译过去炸了,一看日志一个print xxx,直接无语了,真没招。
遇到这种问题,咱们就需要发挥Ubuntu的独有优势------有update alternative。我们可以自己手动编译Python。(我要说三遍!老SDK这样做可能有风险!老SDK这样做可能有风险!老SDK这样做可能有风险!)方法看下面就好:
wget https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz
tar xf Python-2.7.18.tgz
cd Python-2.7.18
./configure
make -j$(nproc)
sudo make install
稍微提醒一下,不要想着搞2.7以下的Python,我可以负责任的说,今天的Linux现代发行版很难,很难编译这种上古时期的Python了,别踩坑,我踩过了。
这个时候,我们还需要额外注意请出来update-alternative了。
当你按照源码编译了 Python 2.7 之后,它通常会被安装在 /usr/local/bin/python2.7 目录下。这时,你可以先简单确认一下安装是否成功,执行:
bash
ls /usr/local/bin/python2*
你应该能看到两个文件:python2.7 和 python2.7-config。前者是 Python 2 的可执行文件,后者提供编译扩展模块时所需的配置参数。至此,你就拥有了一个独立的 Python2 环境,但是仅仅这样还不够,因为系统默认的 python 命令依然指向 Python3,很多老旧的构建脚本如果直接调用 python 就会失败。
为了在同一台机器上优雅地管理多版本 Python,我们可以使用 Ubuntu 的 update-alternatives 系统。这套机制允许你为同一个命令维护多个候选版本,并且可以随时切换默认使用的版本,避免直接覆盖系统默认的 Python3,从而保证系统和工具链的安全性。
首先,我们为 Python3 注册 alternatives 条目。虽然大多数系统已经自带 Python3,并且 /usr/bin/python3 已经存在,但我们仍然可以手动注册并赋予一个较高的优先级:
bash
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 30
接着,我们把刚刚编译的 Python2.7 注册进 alternatives,并赋予一个较低的优先级:
bash
sudo update-alternatives --install /usr/bin/python python /usr/local/bin/python2.7 20
这里的优先级数字非常关键:数字越大,系统默认优先使用的版本就越高。通过这种方式,我们让 Python3 成为默认版本,而 Python2 成为备选版本,这样在不破坏系统环境的前提下,就可以随时为老旧的构建脚本切换到 Python2。
切换命令也非常简单,只需要执行:
bash
sudo update-alternatives --config python
你会看到一个交互式的选择菜单,列出所有注册的 Python 版本以及对应的优先级,例如:
There are 2 choices for the alternative python
Selection Path Priority
-------------------------------------------------
* 0 /usr/bin/python3 30
1 /usr/bin/python3 30
2 /usr/local/bin/python2.7 20
输入数字 2,回车后,系统就会把默认 python 命令切换到你刚编译的 Python2.7。为了确认切换成功,可以执行:
bash
python --version
如果一切顺利,你会看到:
Python 2.7.18
这样,你就完成了一个干净、安全的 Python 多版本管理:系统默认依然是 Python3,而在需要构建老旧 U-Boot 或其他依赖 Python2 的项目时,你可以随时切换到 Python2,避免对系统环境造成破坏。这种方式比直接用 ln -sf 改写 /usr/bin/python 安全得多,也更容易维护和回退。
但是吧,这样搞,可能是有风险的!我之前强调了三遍了,这样搞说明,你已经觉得你可以承担得起后果了。
在编 RK SDK recovery 的时候,你可能会看到这样的报错:
/usr/bin/ld: /usr/local/lib/libpython2.7.a(floatobject.o): relocation R_X86_64_PC32
recompile with -fPIC
collect2: error: ld returned 1 exit status
然后后续一大串模块 _ssl _socket _zlib _sqlite3 ... 都挂掉,整个编译直接崩了。
我们手动装过 Python2:
bash
wget https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz
./configure
make
sudo make install
哦吼,默认安装到了 /usr/local/lib,这个版本的RK SDK 的老 Buildroot 没有严格隔离 host search path → 优先找到 /usr/local/lib ,好了,炸了。
🛠 解决方案
方案 A(推荐):临时移走冲突库
bash
sudo mv /usr/local/lib/libpython2.7.a /usr/local/lib/libpython2.7.a.bak
sudo mv /usr/local/lib/libpython2.7.so /usr/local/lib/libpython2.7.so.bak 2>/dev/null
sudo mv /usr/local/lib/libpython2.7.so.1.0 /usr/local/lib/libpython2.7.so.1.0.bak 2>/dev/null
sudo ldconfig
然后彻底清理 recovery buildroot 的 host-python 并重新编:
bash
cd buildroot
make O=output/rockchip_rk356x_recovery host-python-dirclean
make O=output/rockchip_rk356x_recovery host-python
这样就能保证 host-python 只用 buildroot 自己编出来的干净版本,不会再串库。
方案 B(不动 /usr/local):调整链接路径
bash
export LDFLAGS="-L/usr/lib/x86_64-linux-gnu"
但老 Buildroot 对这个不一定完全支持,稳定性没方案 A 高。
使用Linux 5.10版本的朋友需要注意
好消息,我这边没遇到什么问题,高版本的编译就会非常的丝滑。SDK的验证还是很稳固的。就是平均等待的时间确实会比较久------我分配了8个核心,10G内存,编译了4-5个小时才搞定。主要是在buildroot编译包才出现的。当然,我建议走一轮流程,后面替换的时候会嘎嘎方便。
制作Ubuntu24.04-RootFS
Ubuntu24.04-RootFS很好做,比起来,Arch Linux(我自己尝试的其他发行版)显然更加的刁钻。下面我们就来说说咋搞。
我们请出来的工具------debootstrap 是一个用于引导安装基础 Debian 或 Ubuntu 系统的工具。它可以将一个最小的系统安装到当前已安装系统的子目录中,无需使用安装光盘。它会自动下载基础包并解压安装,构建一个干净的 rootfs 环境 。也就是说,它会自动帮助你配置好一个可以使用的根文件系统。
sudo apt install debootstrap qemu-user-static
sudo debootstrap --arch=arm64 noble ./ubuntu-rootfs http://ports.ubuntu.com/
上面的命令会在执行处文件夹目录下创建rk3568-ubuntu2404-rootfs作为我们的根文件系统,名称随意。记住这个名称。
构建根文件系统的时候,我们是要复用主机的文件夹且进入文件系统进行自动配置。我这里拉出来一个
#!/bin/bash
ROOTFS=rk3568-ubuntu2404-rootfs
sudo mount -t proc proc $ROOTFS/proc
sudo mount -t sysfs sys $ROOTFS/sys
sudo mount -o bind /dev $ROOTFS/dev
sudo mount -t devpts devpts $ROOTFS/dev/pts
sudo chroot $ROOTFS
我们挂载好了必须要的目录之后。就可以进入进行配置了。我们这里先需要将
需要的驱动文件
一些模块的驱动文件需要被拷贝进来,这一点,笔者建议你lsmod一下运行旧的ubuntu的开发板上挂载了什么模块,自己去复制;或者如果更熟悉SDK流程的朋友可以试着用下module install,笔者没搞清楚SDK包是如何指定下载参数的,也没有看到他是如何进行打包的。所以这里不赘述。(笔者lsmod后发现我就需要拷贝一下蓝牙和WiFi驱动就完事,这一步我直接cv了内核的东西就走了,这个没啥好说的)
教各位一个偷懒技巧:去看看自己的buildroot下面的modules有啥,直接cv就好了。(output/target/lib/modules/<kernel_version>/)
安装必备的东西
在我们的Ubuntu24.04根文件系统制作中,首先要安装很多基本的库:
apt install sudo vim udev net-tools ethtool udhcpc netplan.io iputils-ping iw ifconfig wireless_tools
locale-gen en_US.UTF-8
dpkg-reconfigure locales
dpkg-reconfigure tzdata
当然,这里还额外建议配置以下国内的源,具体咋配置:
cp /etc/apt/sources.list /etc/apt/sources.list.bak
先备份,再编辑 /etc/apt/sources.list:
deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
apt update
安装额外工具(可选,但建议)
apt install -y curl wget git build-essential netcat lsof htop
这样,我们的 Ubuntu 根文件系统就具备基本的开发和网络工具了,也能顺利通过国内源下载安装包。防止后面想下点东西发现网络还没配置好,结果一下子全炸了。
创建用户和设置密码
创建用户很简单。但是你最好先给root上密码
passwd
更新密码后,创建一个咱们自己的用户
adduser charliechen
usermod -aG sudo charliechen
charliechen这个名称随意,看你自己的喜好,都是裁剪系统的人了,无需提示这个(笑
这个自己定制,你想让系统啥样是自己所需要的,上面的步骤只是必须要做的动作。
烧录
本质上,我们就是替换 SDK 生成的 EXT2 文件做打包操作,所以整个流程可以拆解为几个步骤:
-
准备新镜像
- 首先,你需要一个新的 rootfs 镜像,比如
custom-rootfs.ext2。 - 它可以是你自己编译的 Buildroot 镜像,也可以是修改过的 Ubuntu 24.04 根文件系统。
- 首先,你需要一个新的 rootfs 镜像,比如
-
检查 SDK 和镜像路径
-
脚本会确认 SDK 的输出目录是否存在,例如:
~/linux510_sdk/buildroot/output/rockchip_atk_dlrk3568/images -
同时检查你提供的镜像文件是否存在,避免路径写错或者文件名拼错。
-
-
备份原有 rootfs
-
如果 SDK 里已有
rootfs.ext2,脚本会自动备份:rootfs.ext2.backup_YYYYMMDD_HHMMSS -
这样即使新镜像有问题,也可以随时恢复。
-
-
替换镜像
-
核心操作就是把你的新镜像复制到 SDK 镜像目录,并命名为
rootfs.ext2:bashcp custom-rootfs.ext2 $SDK_IMAGES_DIR/rootfs.ext2 -
替换完成后,可以通过
ls -lh查看文件信息,确认大小和时间戳。
-
-
可选打包
-
脚本会询问是否立即调用 SDK 打包命令:
bash./build.sh updateimg -
打包后,SDK 会把新的 rootfs 融入完整固件镜像中,生成可烧录的镜像文件。
-
如果不想立即打包,也可以稍后手动执行同样的命令。
-
-
查看备份历史
- 脚本最后会列出最近几个备份,方便你核对历史记录。
cpp
#!/bin/bash
# 定义变量
SDK_PATH="$HOME/linux510_sdk"
SDK_IMAGES_DIR="$SDK_PATH/buildroot/output/rockchip_atk_dlrk3568/images"
BACKUP_DIR="$SDK_IMAGES_DIR/backups"
TARGET_NAME="rootfs.ext2"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 显示使用帮助
show_usage() {
echo "========================================="
echo " RootFS 镜像部署脚本"
echo "========================================="
echo ""
echo "用法: $0 <镜像文件>"
echo ""
echo "参数:"
echo " <镜像文件> 要部署的rootfs镜像文件(相对于当前目录)"
echo ""
echo "示例:"
echo " $0 ubuntu24-rootfs.ext2"
echo " $0 ./images/custom-rootfs.ext2"
echo " $0 ../build/rootfs.img"
echo ""
exit 1
}
# 检查参数
if [ $# -eq 0 ]; then
echo -e "${RED}错误: 未指定镜像文件!${NC}"
echo ""
show_usage
fi
SOURCE_IMG="$1"
echo "========================================="
echo " RootFS 镜像部署脚本"
echo "========================================="
echo -e "${BLUE}源镜像: $SOURCE_IMG${NC}"
echo ""
# 检查源文件是否存在
if [ ! -f "$SOURCE_IMG" ]; then
echo -e "${RED}错误: 源镜像 $SOURCE_IMG 不存在!${NC}"
echo ""
echo "当前目录: $(pwd)"
echo "请检查文件路径是否正确"
echo ""
echo "当前目录下的镜像文件:"
ls -lh *.ext2 *.img 2>/dev/null || echo " 未找到 .ext2 或 .img 文件"
exit 1
fi
# 检查SDK目录是否存在
if [ ! -d "$SDK_IMAGES_DIR" ]; then
echo -e "${RED}错误: SDK镜像目录不存在: $SDK_IMAGES_DIR${NC}"
echo "请检查SDK路径是否正确"
exit 1
fi
# 显示源文件信息
echo "源镜像文件信息:"
ls -lh "$SOURCE_IMG"
echo ""
# 创建备份目录
mkdir -p "$BACKUP_DIR"
# 备份原有的rootfs.ext2(如果存在)
if [ -f "$SDK_IMAGES_DIR/$TARGET_NAME" ]; then
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BACKUP_FILE="$BACKUP_DIR/${TARGET_NAME}.backup_${TIMESTAMP}"
echo -e "${YELLOW}正在备份原有的 rootfs.ext2...${NC}"
cp "$SDK_IMAGES_DIR/$TARGET_NAME" "$BACKUP_FILE"
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ 备份完成: $BACKUP_FILE${NC}"
# 显示备份文件大小
BACKUP_SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
echo " 备份大小: $BACKUP_SIZE"
else
echo -e "${RED}✗ 备份失败!${NC}"
exit 1
fi
else
echo -e "${YELLOW}未找到原有的 rootfs.ext2,跳过备份${NC}"
fi
# 复制新镜像到SDK目录
echo ""
echo -e "${YELLOW}正在部署新镜像到SDK...${NC}"
cp "$SOURCE_IMG" "$SDK_IMAGES_DIR/$TARGET_NAME"
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ 镜像部署成功!${NC}"
echo " 源文件: $(pwd)/$SOURCE_IMG"
echo " 目标位置: $SDK_IMAGES_DIR/$TARGET_NAME"
else
echo -e "${RED}✗ 镜像部署失败!${NC}"
exit 1
fi
# 显示文件信息
echo ""
echo "========================================="
echo "部署后的文件信息:"
ls -lh "$SDK_IMAGES_DIR/$TARGET_NAME"
echo "========================================="
# 询问是否立即打包
echo ""
read -p "是否立即调用SDK打包命令?(y/n): " answer
if [ "$answer" = "y" ] || [ "$answer" = "Y" ]; then
echo ""
echo -e "${YELLOW}正在切换到SDK目录并执行打包...${NC}"
cd "$SDK_PATH"
# 这里根据您的SDK实际打包命令修改
# 常见的RK SDK打包命令:
# ./build.sh updateimg
# 或者
# ./mkfirmware.sh
echo "执行打包命令: ./build.sh updateimg"
./build.sh updateimg
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ 打包完成!${NC}"
else
echo -e "${RED}✗ 打包失败,请检查SDK配置${NC}"
exit 1
fi
else
echo -e "${YELLOW}跳过打包,您可以稍后手动执行:${NC}"
echo " cd $SDK_PATH"
echo " ./build.sh updateimg"
fi
echo ""
echo -e "${GREEN}=========================================${NC}"
echo -e "${GREEN} 所有操作完成!${NC}"
echo -e "${GREEN}=========================================${NC}"
# 显示备份历史
if [ -d "$BACKUP_DIR" ] && [ "$(ls -A $BACKUP_DIR 2>/dev/null)" ]; then
echo ""
echo "历史备份文件 (最近5个):"
ls -lht "$BACKUP_DIR" | head -6
fi
进一步配置
我们没有安装桌面,就是因为,桌面很大,别再上位机安装。否则的话,拷贝就怪烦人的。
挂载模块
记得先挂载下模块,来个例子,比如说我这个就是------
set -euo pipefail
[ "$(id -u)" -eq 0 ] || die "must run as root"
log "=== start system_inits ==="
for ko in 8852bs.ko hci_uart.ko; do
log "Loading $ko"
insmod "/lib/modules/$ko" >/dev/null 2>&1 || die "failed to load $ko"
log "insmod $ko ok"
done
挂载下8852bs.ko hci_uart.ko两个模块。
拉起来网络
我们可以先拉起来网络,我是WLAN无线网,所以先要配置以下网络:
rm -rf /etc/wpa_supplicant.conf # 我喜欢删除旧的先
wpa_passphrase "你WIFI叫啥" "你的密码" > /etc/wpa_supplicant.conf
cat /etc/wpa_supplicant.conf # 自己看一下
然后拉起来看看------
sudo ip link set wlan0 up
sudo wpa_supplicant -i wlan0 -c /etc/wpa_supplicant.conf -B
sudo dhclient -v wlan0 # 得到动态IP
是牛是马ping 8.8.8.8看看,然后ping下baidu.com就行。
配置一下Ubuntu桌面
1. 更新系统
bash
sudo apt update
sudo apt upgrade -y
2. 选择并安装桌面环境
根据RK3568的性能,推荐以下选项:
轻量级(推荐):
bash
# XFCE桌面(资源占用小,流畅)
sudo apt install xubuntu-desktop -y
# 或 LXDE桌面(更轻量)
sudo apt install lubuntu-desktop -y
标准桌面:
bash
# GNOME桌面(Ubuntu默认,但资源占用较大)
sudo apt install ubuntu-desktop -y
3. 安装显示管理器
bash
sudo apt install lightdm -y
# 或使用GDM(GNOME用)
# sudo apt install gdm3 -y
4. 启用图形界面
bash
sudo systemctl set-default graphical.target
sudo reboot
完事。基本上就可以了。