ZYNQ移植Ubuntu根文件系统
(1)拉取系统镜像
Zynq 7000是 32 位处理器,用 armhf 架构,ZynqMP是64位处理器,用arm64,这里用的是zynq7010的垃圾佬矿板所以用是armhf
①准备环境并下载镜像
拉取 Ubuntu 20.04 (Focal) 的最小化系统:
shell
sudo apt update
sudo apt install qemu-user-static debootstrap -y
sudo mkdir ~/ubuntu-rootfs
sudo ln -s /usr/share/debootstrap/scripts/gutsy /usr/share/debootstrap/scripts/focal
sudo qemu-debootstrap --arch armhf --variant=minbase --verbose focal ~/ubuntu-rootfs/ http://mirrors.ustc.edu.cn/ubuntu-por
等待下载完成, ~/ubuntu-rootfs/ 目录下就会生成基础的 Linux 目录结构
(2)环境挂载与系统切换
需要借用宿主机的硬件节点,让刚刚那个空壳系统能够联网和运行
①复制网络解析配置
空壳系统马上需要用 apt update去网上下载软件。虽然宿主机有网络,但空壳系统内部不知道 DNS 服务器是谁,所以把这个网络解析配置给它
shell
sudo cp -b /etc/resolv.conf ~/ubuntu-rootfs/etc/resolv.conf
②创建并执行挂载脚本
Linux 有一个核心哲学:一切皆文件。系统的运行状态、硬件设备,都是以"文件"的形式存在于 /proc、/sys 和 /dev 这几个目录里的。 因为空壳系统没有自己真正运行的内核,所以必须把宿主机电脑的这几个目录映射到空壳系统的对应目录里
创建一个名为 ch-mount.sh 的文件:
shell
nano ch-mount.sh
将以下脚本内容完整粘贴进去:
shell
#!/bin/bash
function help() {
echo "usage: ch-mount.sh [-m <path>] [-u <path>] <command> [<args>]"
}
while getopts "m:u:" arg
do
case $arg in
m)
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}
;;
u)
sudo umount ${2}proc
sudo umount ${2}sys
sudo umount ${2}dev/pts
sudo umount ${2}dev
;;
?)
help
exit 1
esac
done
保存退出后,赋予执行权限并挂载进入环境:
shell
chmod +x ch-mount.sh
sudo bash ch-mount.sh -m ~/ubuntu-rootfs/
执行成功后,终端提示符会发生变化,说明已经进入了 Zynq 的 ARM 系统内部。接下来的命令都在这个新环境下执行

(3)根文件系统精装修
①配置 Ubuntu 20.04 国内源
shell
cat > /etc/apt/sources.list << EOF
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ focal main universe restricted multiverse
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ focal-updates main universe restricted multiverse
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ focal-backports main universe restricted multiverse
deb http://mirrors.ustc.edu.cn/ubuntu-ports/ focal-security main universe restricted multiverse
EOF
apt update
②安装必备软件包与开发工具
ubuntu的空壳系统是自带apt和 dpkg,因此为啥这一步不在板子上做呢,因为这个空没有有 NetworkManager,也没有 dhclient(自动获取 IP 的工具),甚至连 ping和 ifconfig都没有,所以根本连不上网
除了基础的网络和系统管理工具,这里特意加入了 libiio-utils 和 i2c-tools。在 Zynq 平台上调试高速数据采集和无线电通信外设时,这些工具配合 Linux 内核驱动会极其顺手,能直接跨越 PL/PS 端读取数据
shell
apt install language-pack-en-base sudo ssh net-tools wireless-tools network-manager iputils-ping rsyslog bash-completion htop vim kmod libiio-utils i2c-tools build-essential --no-install-recommends -y
③账户与权限设置
shell
# 设置 root 密码
passwd root
# 添加日常用户 (按提示输入密码)
adduser zyc
# 赋予该用户 sudo 权限
echo "zyc ALL=(ALL:ALL) ALL" >> /etc/sudoers
# 设置主机名与本地解析
echo "zynq7010" > /etc/hostname
echo "127.0.0.1 localhost" >> /etc/hosts
echo "127.0.1.1 zynq7010" >> /etc/hosts
(4)Zynq 专属底层适配
这是决定系统能否在板子上正常跑起来的最关键步骤。当内核完成底层硬件的初始化后,它会根据 U-Boot 传递的启动参数(bootargs,例如 root=/dev/mmcblkXp2),直接去 SD 卡定位并强行挂载初步的根文件系统。踹开大门后,内核随即将系统的控制权全权交接给 Ubuntu 的一号进程 systemd。随后,接管大权的 systemd 才会去读取你配置的 /etc/fstab,对根目录应用高级挂载属性(如只读保护、取消访问时间记录),并挂载其他辅助分区(如 /boot/uboot)
①开启 Zynq 硬件串口登录 (Systemd 方式)
Zynq 的默认 PS 端串口为 ttyPS0。抛弃老旧的 Upstart,直接激活 Systemd 服务
shell
systemctl enable serial-getty@ttyPS0.service
②配置 SD 卡分区挂载表 (fstab)
/etc/fstab(File System Table)就是一张明确的开机挂载表,系统每次开机都会严格按照这张表去寻找并挂载硬盘分区
Zynq 从 SD 卡启动时,我的zynq7010的SD 卡被识别为 /dev/mmcblk0,但zynqMP被识别为/dev/mmcblk1
shell
cat > /etc/fstab << EOF
# <file system> <dir> <type> <options> <dump> <pass>
/dev/mmcblk0p2 / ext4 defaults,noatime,errors=remount-ro 0 1
/dev/mmcblk0p1 /boot/uboot vfat defaults,noatime 0 0
EOF
(5)清理战场与打包收尾
①清除下载缓存并退出环境
shell
apt clean
exit
②卸载硬件节点
退回到 x86 虚拟机的终端后,务必执行解挂载命令,防止损坏宿主机:
shell
sudo bash ch-mount.sh -u ~/ubuntu-rootfs/
③最终的烧录准备
至此,ubuntu根文件系统已经制作完毕。接下来你需要准备一张 SD 卡,将其分为两个区:
- 第一个分区 (FAT32): 放入用Petalinux 编译出来的
BOOT.BIN和image.ub和boot.scr - 第二个分区 (EXT4): 将
~/ubuntu-rootfs/目录下的所有文件原封不动地cp -a拷贝进去
shell
sudo cp -a ~/ubuntu-rootfs/. /目标位置
参考文档
制作适用于ZYNQ(ARM平台)的Ubuntu系统_zynq ubuntu-CSDN博客
Gemini