AM5728实战:从零构建ARM Ubuntu 20.04定制根文件系统

1. 为什么需要从零构建根文件系统?

很多刚接触TI AM5728这类高性能工业处理器的朋友,拿到开发板后,第一反应往往是直接使用厂商提供的现成系统镜像。这当然没问题,能快速上手。但当你真正想把这块板子用到自己的产品里,比如做个智能网关、视觉控制器或者边缘计算盒子时,现成的系统就开始“水土不服”了。

我遇到过最典型的情况是,项目需要一套极其精简的系统,只运行一个后台服务,但原厂镜像里塞满了各种用不上的图形界面、开发工具和测试软件,不仅占用宝贵的eMMC或SD卡空间,启动慢,还可能引入不必要的安全风险。又或者,你需要一个特定版本的软件库,而原厂镜像的软件源版本太旧,手动升级又常常遇到依赖地狱。这时候,从零开始构建一个量身定制的根文件系统,就成了必经之路。

所谓“根文件系统”,你可以把它理解成嵌入式Linux系统的“五脏六腑”和“家当”。内核负责驱动硬件、管理进程这些底层核心事务,而根文件系统则包含了系统运行所需的所有基础命令(比如lscp)、配置文件、库文件以及你的应用程序。它为整个系统提供了运行环境。为AM5728这样的ARM Cortex-A15/A7平台构建Ubuntu根文件系统,本质上就是在你的x86电脑上,为另一个架构的CPU准备一个完整的、可运行的软件家园。

这个过程听起来有点跨次元,但得益于qemu-user-static这样的神器,我们可以在自己的电脑里模拟出一个ARM环境,就像在电脑里开辟了一个独立的“ARM虚拟空间”,然后在这个空间里安装软件、配置系统,最后打包成一个完整的镜像,烧写到AM5728上就能直接跑起来。这么做的好处太多了:极度可控,系统里每一个软件都是你亲手挑选安装的;高度精简,没有一丝多余的赘肉;深度定制,从网络配置、用户权限到开机自启服务,完全按你的想法来。

接下来,我就带你走一遍我实战过多次的完整流程,从准备“建筑材料”(基础系统),到搭建“施工环境”(QEMU),再到“精装修”(安装软件、配置系统),最后“交付成品”(生成镜像)。我会把每一步的原理、操作命令和最容易踩的坑都讲清楚,确保你跟着做就能成功。

2. 准备构建环境与基础原料

工欲善其事,必先利其器。在开始“施工”前,我们需要准备好两样东西:一是构建系统所需的“原材料”,也就是最基础的Ubuntu文件系统;二是一个能在我们电脑(通常是x86_64架构)上运行ARM程序的“模拟施工队”。

2.1 获取Ubuntu基础文件系统:两种方法对比

获取ARM架构的Ubuntu基础文件系统,主要有两种主流方法,各有优劣,我两种都试过,下面给你详细拆解。

第一种方法:直接从Ubuntu官网下载基础包。 这是我最推荐新手使用的方法,简单、直接、速度快。Ubuntu官方提供了为嵌入式场景准备的“Ubuntu Base”镜像,这是一个非常精简的根文件系统,只包含最核心的包管理器(apt)、shell(bash)和最基本的工具。

操作起来很简单。打开浏览器,访问 http://cdimage.ubuntu.com/ubuntu-base/releases/。找到20.04 LTS(长期支持版)的目录,因为LTS版本稳定,支持周期长。对于AM5728这种带硬浮点单元的ARM处理器,我们选择 armhf 架构的版本。具体文件通常是 ubuntu-base-20.04.x-base-armhf.tar.gz。你可以直接在Ubuntu虚拟机里用wget命令下载:

wget http://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/ubuntu-base-20.04.5-base-armhf.tar.gz

注意版本号可能会更新,以官网最新为准。这个方法下载的是一个已经编译打包好的基础系统,省去了从网络下载大量基础包的等待时间,特别适合国内网络环境。

第二种方法:使用debootstrap工具从头构建。 这个方法更“Geek”,也更具灵活性。debootstrap是一个工具,它的作用是从Ubuntu的软件仓库中,下载指定架构和版本的所有基础软件包,并在本地目录中组装成一个完整的根文件系统。理论上,你可以构建任何Ubuntu版本、任何架构的系统。

命令看起来是这样的:

sudo apt-get install debootstrap qemu-user-static binfmt-support
sudo qemu-debootstrap --arch=armhf --variant=minbase focal ./focal-armhf http://mirrors.ustc.edu.cn/ubuntu-ports/

这条命令分解一下:--arch=armhf指定架构;--variant=minbase指定构建一个最小化的基础系统;focal是Ubuntu 20.04的代号;./focal-armhf是目标目录;最后是软件源地址,这里用了中科大的镜像加速。

听起来很美好,对吧?但我必须给你泼盆冷水:除非你有非常好的国际网络环境,否则这个过程可能会极其缓慢甚至失败。因为它需要从软件源实时下载上百个软件包,而ubuntu-ports仓库对某些国内网络支持并不理想。我早期尝试时,经常卡在某个包下载上,一等就是半天。所以,对于大多数国内开发者,我强烈建议采用第一种方法,先拿到基础包,后续的定制工作在网络环境良好的chroot里进行,体验会好很多。

2.2 配置QEMU跨架构模拟环境

无论你用哪种方法拿到了基础文件系统的压缩包,解压后它只是一堆ARM架构的二进制文件。你没法直接在x86电脑上运行armhf的程序。这时候,qemu-user-static就闪亮登场了。

它的原理非常巧妙。Linux内核有一个叫binfmt_misc的机制,可以识别不同格式的可执行文件,并调用指定的解释器来运行它。qemu-user-static提供了一个静态编译的qemu-arm-static程序,它就是一个解释器。当我们把这个解释器放到ARM根文件系统的/usr/bin目录下,并通过binfmt_misc注册后,系统再遇到ARM程序时,就会自动调用qemu-arm-static来模拟执行。

安装和配置一气呵成:

# 安装必要的软件包
sudo apt-get update
sudo apt-get install qemu-user-static binfmt-support

# 解压基础文件系统 (假设你已经下载了tar包)
sudo mkdir -p ./am5728-rootfs
sudo tar -xpf ubuntu-base-20.04.x-base-armhf.tar.gz -C ./am5728-rootfs

# 将QEMU静态解释器复制到目标根文件系统中
sudo cp /usr/bin/qemu-arm-static ./am5728-rootfs/usr/bin/

复制qemu-arm-static这一步是关键!它相当于在ARM系统的“家”里放了一把万能钥匙(模拟器),这样我们后续用chroot“进入”这个家时,才能在里面正常执行apt-get install等命令。

这里有个小细节:解压时我用了 -p 参数(tar -xpf),这个参数会保留文件原有的权限属性,非常重要。根文件系统里很多文件(比如/bin/bash)需要有可执行权限,丢失了会导致系统无法启动。

3. 深入chroot环境:系统的“精装修”阶段

现在,我们有了一个空的“毛坯房”(基础根文件系统)和一把“钥匙”(qemu模拟器)。接下来,我们要进入这个房子内部,进行水电安装、墙面刷漆、家具进场,也就是安装软件和配置系统。chroot命令就是我们的“任意门”。

3.1 挂载虚拟文件系统与网络配置

直接chroot进去还不够,因为一个正在运行的Linux系统依赖于几个关键的虚拟文件系统,比如/proc(进程信息)、/sys(系统设备信息)、/dev(设备文件)。我们需要在chroot之前,把这些宿主机的虚拟文件系统“绑定挂载”到目标根文件系统的对应目录下。

我习惯用一个脚本来完成挂载和卸载,避免每次手动输入一长串命令。这个脚本通常叫ch-mount.sh,内容如下:

#!/bin/bash
MOUNT_DIR=$2

function mnt() {
    echo "Mounting into $MOUNT_DIR"
    sudo mount -t proc /proc  ${MOUNT_DIR}proc
    sudo mount -t sysfs /sys ${MOUNT_DIR}sys
    sudo mount -o bind /dev ${MOUNT_DIR}dev
    sudo mount -o bind /dev/pts ${MOUNT_DIR}dev/pts
    # 复制DNS配置,保证chroot内能解析域名
    sudo cp /etc/resolv.conf ${MOUNT_DIR}etc/resolv.conf
    # 执行chroot
    sudo chroot $MOUNT_DIR
}

function umnt() {
    echo "Unmounting from $MOUNT_DIR"
    sudo umount ${MOUNT_DIR}proc
    sudo umount ${MOUNT_DIR}sys
    sudo umount ${MOUNT_DIR}dev/pts
    sudo umount ${MOUNT_DIR}dev
}

if [ "$1" == "-m" ] && [ -n "$2" ]; then
    mnt $1 $2
elif [ "$1" == "-u" ] && [ -n "$2" ]; then
    umnt $1 $2
else
    echo "Usage:"
    echo "  $0 -m <mount_dir>  # Mount and chroot"
    echo "  $0 -u <mount_dir>  # Unmount"
fi

给脚本执行权限后,用它来挂载并进入我们的根文件系统:

sudo ./ch-mount.sh -m ./am5728-rootfs/

执行成功后,你的命令行提示符可能不会有明显变化,但此时你已经“穿越”到了为AM5728准备的ARM Ubuntu环境里了!你可以运行 uname -m 验证一下,应该会显示 armv7l

第一个关键配置:换软件源。 默认的Ubuntu官方源在国外,在chroot环境里更新会慢得让你怀疑人生。第一步就是换成国内镜像源。这里我推荐中科大(ustc)或阿里云的源。

# 在chroot环境内执行
cat > /etc/apt/sources.list << EOF
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ focal main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ focal-updates main restricted universe multiverse
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ focal-security main restricted universe multiverse
EOF

注意URL中的 ubuntu-ports,这是专门为非x86架构(如ARM)准备的仓库分支,用错了会导致安装失败。

3.2 基础软件包安装与系统更新

配置好源,就可以开始安装软件了。首先更新软件包列表并升级现有软件:

apt-get update
apt-get upgrade -y

接下来,安装一些嵌入式系统必备的“生存包”。这个列表是我多年总结的,兼顾了实用性和精简性:

apt-get install -y \
    sudo vim git curl wget \
    net-tools iputils-ping ifupdown isc-dhcp-client \
    ssh openssh-server \
    udev systemd-sysv \
    rsyslog kmod \
    locales tzdata
  • 网络工具net-tools(ifconfig)、iputils-pingifupdown是配置网络的基础。
  • SSHopenssh-server让你能远程登录,这是调试和管理的生命线。
  • 设备管理udev负责动态创建设备节点,没有它,插上U盘或网卡系统可能识别不了。
  • 日志与模块rsyslog记录系统日志,kmod用于加载内核模块。
  • 本地化localestzdata设置语言环境和时区,避免时间错乱。

安装时务必加上 -y 参数,避免中途需要确认。这个过程会下载并安装不少包,取决于你的网络速度,需要耐心等待几分钟。

4. 针对AM5728的深度定制与配置

基础软件装好了,但这还是个“通用”的ARM系统。要让它能在AM5728开发板上跑得顺畅,还需要做一些针对性配置。

4.1 网络与主机名配置

嵌入式设备通常需要固定的IP或DHCP。我们配置一个以太网接口eth0使用DHCP,这适合大多数有路由器的场景。

# 创建网络接口配置文件
cat > /etc/network/interfaces.d/eth0 << EOF
auto eth0
iface eth0 inet dhcp
EOF

如果你需要静态IP,可以这样配置:

cat > /etc/network/interfaces.d/eth0 << EOF
auto eth0
iface eth0 inet static
    address 192.168.1.100
    netmask 255.255.255.0
    gateway 192.168.1.1
    dns-nameservers 8.8.8.8
EOF

接着设置主机名,这会在命令行提示符和日志中显示:

echo "am5728-ubuntu" > /etc/hostname
echo "127.0.0.1 localhost am5728-ubuntu" >> /etc/hosts

4.2 用户、密码与安全基线

默认的根文件系统没有设置root密码,这是不安全的,也必须设置才能登录。

# 设置root密码,会提示你输入两次
passwd root

我强烈建议创建一个日常使用的普通用户,避免总是用root操作:

adduser engineer
# 按照提示设置密码、全名等信息
# 将用户加入sudo组,使其拥有管理员权限
usermod -aG sudo engineer

一个关键的安全设置:禁用串口调试登录。AM5728开发板通常通过串口连接。在/etc/systemd/system/getty.target.wants/目录下,你会找到一个类似serial-getty@ttyS0.service的链接。如果你不需要从串口登录,可以移除它,避免安全漏洞:

systemctl disable serial-getty@ttyS0.service

4.3 安装与配置开发环境

根据你的项目需求,安装必要的运行时和开发工具。例如,如果你的应用是Python写的:

# 安装Python3及常用工具
apt-get install -y python3 python3-pip python3-venv
# 安装一些常用的Python库
pip3 install --no-cache-dir numpy pyserial

如果需要C/C++开发环境:

apt-get install -y build-essential cmake git gdb

对于需要Java运行环境的:

apt-get install -y default-jdk-headless

注意:在嵌入式环境,尽量安装-headless版本(无图形界面依赖)的软件,以节省空间。

5. 清理、打包与生成最终镜像

系统配置得差不多了,是时候“封房验收”,准备交付给AM5728了。

5.1 退出chroot与清理工作

首先,在chroot环境内执行exit退出,回到宿主机的shell。然后,使用之前那个脚本卸载虚拟文件系统:

sudo ./ch-mount.sh -u ./am5728-rootfs/

重要! 在打包前,必须进行清理,以减小最终镜像体积。

  1. 清理APT缓存apt-get下载的软件包安装文件都缓存在/var/cache/apt/archives/,可以安全删除。
    sudo rm -rf ./am5728-rootfs/var/cache/apt/archives/*.deb
    sudo rm -rf ./am5728-rootfs/var/lib/apt/lists/*
    
  2. 清理临时文件
    sudo rm -rf ./am5728-rootfs/tmp/*
    sudo rm -rf ./am5728-rootfs/var/tmp/*
    
  3. 删除文档和手册(如果空间极其紧张):
    sudo find ./am5728-rootfs/usr/share/doc -type f -delete
    sudo find ./am5728-rootfs/usr/share/man -type f -delete
    
  4. 移除QEMU模拟器:这个只是构建时用的,板子上不需要。
    sudo rm ./am5728-rootfs/usr/bin/qemu-arm-static
    

5.2 打包根文件系统并制作SD卡镜像

现在,将定制好的根文件系统目录打包成一个压缩包,方便传输和后续制作镜像。

sudo tar -czpf ubuntu-20.04-am5728-rootfs.tar.gz -C ./am5728-rootfs .

接下来,你需要将这个根文件系统放到一个完整的SD卡镜像中,这个镜像通常包含引导分区(存放U-Boot和内核设备树)和根文件系统分区。具体步骤依赖于你使用的SD卡制作工具和AM5728的引导方式。

以常见的使用mkimagedd工具为例,假设你已经有一个预编译好的U-Boot (MLO, u-boot.img)、Linux内核(zImage)和设备树(*.dtb):

  1. 准备一个空镜像文件,并分区(通常第一个FAT分区放引导文件,第二个ext4分区放根文件系统)。
  2. 将引导文件拷贝到第一个FAT分区。
  3. 将我们制作的ubuntu-20.04-am5728-rootfs.tar.gz解压到第二个ext4分区。
  4. 使用dd命令将整个镜像写入SD卡。

由于不同厂商的AM5728核心板或开发板其引导流程和分区表可能有细微差别,这里不展开具体命令。最稳妥的方法是参考你所用硬件厂商提供的《系统烧写指南》,用你制作好的根文件系统压缩包替换掉他们指南中对应的那个文件。通常厂商会提供一个脚本(比如mk-sdcard.sh),你只需要把压缩包放在指定目录,运行脚本即可自动完成分区、格式化、拷贝和设置。

6. 上板测试与常见问题排坑

将烧写好的SD卡插入AM5728开发板,上电启动。通过串口调试终端,你应该能看到内核启动日志,最后出现登录提示符。用你设置的root或普通用户密码登录。

踩坑记录一:SSH登录失败 如果你安装了openssh-server却无法用SSH连接,提示密码错误。除了检查密码和网络,一个常见原因是SSH默认配置禁止root登录。你可以修改/etc/ssh/sshd_config文件:

PermitRootLogin yes

然后重启SSH服务:systemctl restart sshd

踩坑记录二:系统时间不对 如果系统时间显示的是UTC时间或非常奇怪的时间,是因为没有正确设置时区。在构建时我们安装了tzdata,可以在板子上运行dpkg-reconfigure tzdata交互式选择时区,或者用非交互方式设置:

echo "Asia/Shanghai" > /etc/timezone
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

踩坑记录三:图形界面(如果需要) 如果你安装了桌面环境(如xubuntu-desktop),但启动后黑屏或无法进入桌面,很可能是显示驱动或显示管理器的问题。对于AM5728,TI的GPU驱动可能需要额外的固件或配置。对于大多数嵌入式应用,我建议不要安装完整的桌面环境,而是根据需要安装轻量级的窗口管理器或直接运行基于Qt、GTK的图形应用,这能节省大量资源并提高稳定性。

构建一个完全属于自己的根文件系统,第一次成功启动的那一刻成就感十足。整个过程就像在虚拟世界里为另一块芯片精心打造一个家园,每一个软件、每一项配置都了然于胸。当你的定制系统在AM5728上稳定运行时,那种对系统的掌控感,是使用现成镜像无法比拟的。后续你可以把这个根文件系统压缩包作为模板,为不同的项目快速衍生出新的定制版本,开发效率会大大提升。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值