RK3568跑Ubuntu 24.04全路程指南(以正点原子的RK3568开发板为例子)

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.7python2.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 文件做打包操作,所以整个流程可以拆解为几个步骤:

  1. 准备新镜像

    • 首先,你需要一个新的 rootfs 镜像,比如 custom-rootfs.ext2
    • 它可以是你自己编译的 Buildroot 镜像,也可以是修改过的 Ubuntu 24.04 根文件系统。
  2. 检查 SDK 和镜像路径

    • 脚本会确认 SDK 的输出目录是否存在,例如:

      复制代码
      ~/linux510_sdk/buildroot/output/rockchip_atk_dlrk3568/images
    • 同时检查你提供的镜像文件是否存在,避免路径写错或者文件名拼错。

  3. 备份原有 rootfs

    • 如果 SDK 里已有 rootfs.ext2,脚本会自动备份:

      复制代码
      rootfs.ext2.backup_YYYYMMDD_HHMMSS
    • 这样即使新镜像有问题,也可以随时恢复。

  4. 替换镜像

    • 核心操作就是把你的新镜像复制到 SDK 镜像目录,并命名为 rootfs.ext2

      bash 复制代码
      cp custom-rootfs.ext2 $SDK_IMAGES_DIR/rootfs.ext2
    • 替换完成后,可以通过 ls -lh 查看文件信息,确认大小和时间戳。

  5. 可选打包

    • 脚本会询问是否立即调用 SDK 打包命令:

      bash 复制代码
      ./build.sh updateimg
    • 打包后,SDK 会把新的 rootfs 融入完整固件镜像中,生成可烧录的镜像文件。

    • 如果不想立即打包,也可以稍后手动执行同样的命令。

  6. 查看备份历史

    • 脚本最后会列出最近几个备份,方便你核对历史记录。
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

完事。基本上就可以了。

相关推荐
GeminiJM1 小时前
LangGraph 源码学习笔记
linux·笔记·学习·langchain
MyFreeIT1 小时前
OpenSSL
linux·运维·服务器
瀚高PG实验室1 小时前
hghac8008漏洞扫描处理
linux·网络·windows·瀚高数据库
小龙1 小时前
【学习笔记】视频抽帧方法大全
笔记·学习·计算机视觉·视频·视频抽帧
AD钙奶-lalala2 小时前
Error starting ApplicationContext. To display the condition evaluation···
linux·运维·服务器
71ber2 小时前
RHCSE 实战笔记: LVS 负载均衡集群深度解析
linux·服务器·lvs
一只小小的芙厨2 小时前
寒假集训·子集枚举2
c++·笔记·算法·动态规划
Byte不洛2 小时前
TCP 服务器如何支持高并发?单进程、多进程、多线程模型详解
linux·网络编程·高并发·tcp·socket编程
Jia ming2 小时前
Linux内核动态调试技术揭秘
linux·内核动态调试