- 桌面应用
- 灾备
【免费下载链接】rescuezilla
The Swiss Army Knife of System Recovery
Rescuezilla 的 ISO 镜像本质上是一个可写入 U 盘、可光驱启动、且兼容 EFI Secure Boot 的 Ubuntu 桌面 Linux Live 环境。本文以官方构建文档docs/build_instructions/BUILD.ISO.IMAGE.md为主线,结合仓库内的 Makefile、src/scripts/build.sh 与 Dockerfile 源码,完整讲清楚“不带 Docker 直接构建”“使用 Docker 构建”两条路径的每一步命令、构建系统的目标依赖关系、chroot 装配与 squashfs/EFI 打包原理,以及为什么构建环境必须是 Canonical 的 Ubuntu 包体系。
一、构建产物与两条构建路径
Rescuezilla 面向开发者提供两类产物,均由顶层 Makefile 驱动:
- 独立 deb 安装包:
make deb一条命令即可产出 Rescuezilla 前端应用及其配套应用的 deb 包,适合只想提交前端代码、或想在自己系统上安装 Rescuezilla 的开发者(Debian/Ubuntu/Linux Mint 用户也可直接下载官方发布的 standalone deb 包); - 完整 ISO 镜像:一条
make all命令即可生成可启动 ISO。文档描述其为“完整的、基于 Ubuntu 的 Linux Live 环境”,可从 U 盘、CD/DVD 以及任何 EFI 固件启动,并且EFI Secure Boot 开启时同样可用。
需要注意仓库现状与文档的差异:文档写作时make all同时产出 AMD64 与 i386 两个镜像;当前 Makefile 中all目标仅映射到focal(见 Makefile),而 i386 32 位镜像对应独立的bionic-i386目标(基于最后一个提供 32 位的 Ubuntu LTS 版本 18.04 Bionic)。当前 Makefile 还提供jammy(22.04)、noble(24.04 LTS)、noble-arm64(ARM64 测试构建)、oracular、plucky(当前.DEFAULT_GOAL,即直接运行make的默认目标)、questing、resolute等按 Ubuntu 版本代号命名的目标,构建新镜像时以 Makefile 中的目标列表为准。
二、构建环境要求:为什么必须是 Ubuntu
文档明确给出了非 Docker 构建的环境前提:
- 需要Ubuntu 18.04 或类似的 Ubuntu 包环境,且该环境能够运行
debootstrap、chroot与 bind mount; - 强烈建议仅在 Ubuntu 环境构建 ISO。Debian 及其他非 Canonical 包环境中的 GRUB 相关包签名方式不同,会破坏 Secure Boot(详见第六节);
- 构建脚本需要 root 权限执行 chroot 的 bind mount,因此最终构建命令形如
sudo make <codename>。这一要求可以直接在源码中印证:src/scripts/build.sh 在开头就检查了EUID,非 root 直接退出。
ramdisk 加速(可选)
构建脚本的每一步都要解包/安装大量 deb 文件,对磁盘 IO 敏感。文档给出了一条可选优化:把源码整体放进 tmpfs 内存盘再构建:
# 可选:Rescuezilla 贡献者建议在 ramdisk 上构建以提升构建性能。 # 由于内存需求高、复杂度大,大多数用户可以选择跳过。 # 例如 BASE_BUILD_DIRECTORY=/mnt/ramdisk make focal,或把整个源码目录拷入 ramdisk。 mkdir /mnt/ramdisk/ sudo mount -t tmpfs -o rw,size=7G tmpfs /mnt/ramdisk/ rsync -av `pwd` /mnt/ramdisk cd /mnt/ramdisk/rescuezilla其中BASE_BUILD_DIRECTORY是 Makefile 定义的构建根目录变量(默认为$(shell pwd)/build,见 Makefile),build.sh会以其为前缀创建build/<CODENAME>.<ARCH>子目录。如果不确定是否应该使用 ramdisk,文档建议直接跳过这些步骤。
三、不带 Docker 构建:完整命令序列
以下命令序列来自文档原文(其参考了仓库Dockerfile与 CI 构建流程,会随上游版本变化而有过期可能,若你的构建环境基于不同版本的 Debian/Ubuntu,请以构建报错信息和 src/scripts/build.sh 中的提示为准):
sudo apt update sudo apt install -f git-lfs git make sudo \ rsync debootstrap gettext squashfs-tools dosfstools mtools xorriso \ memtest86+ devscripts debhelper checkinstall cmake time parallel \ grub-efi-amd64-bin grub-efi-ia32-bin grub-pc-bin \ shim-signed grub-efi-amd64-signed \ libtool-bin gawk pkg-config comerr-dev docbook-xsl e2fslibs-dev fuse3 \ libaal-dev libblkid-dev libbsd-dev libncurses5-dev \ libncursesw5-dev libntfs-3g89 libreadline-dev libreadline8 readline-common \ libreiser4-dev libtinfo-dev libxslt1.1 nilfs-tools ntfs-3g ntfs-3g-dev \ quilt sgml-base uuid-dev vmfs-tools xfslibs-dev xfsprogs xml-core \ xsltproc ccache libssl-dev git lfs clone https://github.com/rescuezilla/rescuezilla cd rescuezilla/ git submodule init # 下载 'partclone' 与 'util-linux' 等子模块 git submodule update --recursive # 可选:仅构建 standalone deb 包,不构建 Live 环境 make deb # (可选 ramdisk 步骤,见上一节) # 构建基于指定 Ubuntu 版本的 amd64 ISO 镜像及 deb 文件 # 需要 sudo(chroot bind mount)。 # 注意:此命令在 Ubuntu 或 Ubuntu 衍生发行版上可用, # 不推荐在 Debian 或 Debian 衍生环境执行(见 Secure Boot 一节) sudo make jammy # 在虚拟机中测试生成的 ISO 镜像 sudo apt-get install virtualbox几个关键命令的源码级说明:
git lfs clone:仓库使用 Git LFS 管理部分二进制文件(见 .gitattributes),因此普通git clone无法获得完整内容;git submodule update --recursive:仓库通过 .gitmodules 声明了 5 个第三方子模块——util-linux(编译sfdisk)、partclone-latest(核心增量备份引擎)、partclone-utils、partclone-nbd以及debootstrap(仓库自带一份较新 debootstrap 源码,用于引导基础系统,见 src/scripts/build.sh 与 src/scripts/build.sh);make deb:见下一节。
四、Makefile 构建体系:目标依赖与缓存
顶层 Makefile 是整个构建系统的入口,理解它的目标依赖关系能解释“为什么一条make focal会构建出 ISO”。
4.1 codename 目标与依赖链
每个版本目标(以focal为例)结构相同(Makefile):
focal: CODENAME=focal export ARCH CODENAME focal: deb sfdisk.v2.20.1.amd64 partclone-latest partclone-nbd $(buildscripts) BASE_BUILD_DIRECTORY=$(BASE_BUILD_DIRECTORY) /usr/bin/time ./src/scripts/build.sh即:先产出 4 类前置产物,再调用src/scripts/build.sh完成 ISO 装配:
| 依赖目标 | 作用 | 源码位置 |
|---|---|---|
deb | 编译rescuezilla与graphical-shutdown两个应用包,输出到build/deb/ | Makefile |
sfdisk.v2.20.1.amd64 | 从util-linux子模块编译特定版本的sfdisk,用于恢复 Redo Backup v1.0.4 的备份(该工具链存在向后兼容性问题) | Makefile |
partclone-latest | 编译 partclone 0.3.47 并用checkinstall打成 deb(启用 extfs/reiser4/ntfs/fat/exfat/apfs/btrfs/minix/f2fs/nilfs2 等文件系统) | Makefile |
partclone-nbd | 用 CMake + cpack 构建 partclone-nbd 0.0.4(Image Explorer 特性挂载 partclone 镜像的底层程序) | Makefile |
buildscripts | build.sh与两个 chroot 脚本存在性依赖 | Makefile |
4.2 deb 包的生成方式
deb目标分别进入 src/apps/rescuezilla/ 与 src/apps/graphical-shutdown/ 执行子 Makefile,二者都通过 src/apps/package-as-deb.mk 完成打包:先用git describe --tags计算VERSION_STRING并做版本/提交日期字符串替换(src/apps/package-as-deb.mk),再打 orig/debian 两个 tarball 并调用dpkg-buildpackage -b -us -uc(src/apps/package-as-deb.mk)。dpkg-buildpackage内部又会回调 src/apps/common.app.mk 的msgfmt目标,把所有*.poGTK 翻译编译为二进制*.mo文件。
4.3 包缓存与 clean 目标
文档“Suggested developer workflow”一节强调:构建脚本会缓存 debootstrap 包、apt 包与 apt 索引,首次构建可能下载数百 MB 的 deb 包,之后则无需重复下载。这个缓存目录默认是pkg.cache/,由两个 clean 目标区分处理(Makefile):
make clean:删除 apt索引缓存但保留deb 包缓存,使下次构建只需apt-get update拉取索引,新包才需要下载;make clean-all:索引与包缓存全部删除;make clean-build-dir:卸载各 chroot 的/dev /proc /sysbind mount 并删除整个build/目录(Makefile),构建中断后残留挂载时尤其有用。
缓存机制的实现分布在 src/scripts/build.sh(PKG_CACHE_DIRECTORY等变量)、src/scripts/build.sh(把缓存的 apt archives 与 lists 拷入 chroot)以及 src/scripts/chroot-steps-part-1.sh(按sources.list校验和决定复用还是重新apt-get update)。
此外还有make test(运行 Python 单元测试,Makefile)、make integration-test(启动 VirtualBox 集成测试套件,Makefile)以及make status(打印各 git 子模块状态,辅助排查工作区不干净的问题)。
五、build.sh:ISO 装配的底层流程
make <codename>最终执行的是 src/scripts/build.sh。读懂这份脚本,就理解了 Rescuezilla ISO 是如何从 chroot 一步步变成可启动光盘镜像的。
5.1 版本号与源镜像自动探测
- 版本号来自
git describe --tags(未打 tag 时为X.Y.Z-abc-gGITSHA-dirty格式),提交日期取自git show的时间戳(src/scripts/build.sh),二者会被sed替换进 GRUB 主题、Firefox 策略文件等占位符(src/scripts/build.sh); - 由于 EOL 版本的 Ubuntu 仓库会被移到
old-releases镜像,脚本会先探测dists/$CODENAME/Release的 HTTP 状态码,404 时自动切换到old-releases.ubuntu.com(src/scripts/lib.sh)。
5.2 debootstrap 两阶段引导
脚本使用仓库自带的 debootstrap(src/third-party/debootstrap子模块)以“两阶段法”构建基础系统(src/scripts/build.sh):
debootstrap --foreign仅把基础 deb 包下载/解包到缓存目录(若缓存已存在则跳过);rsync到build/<CODENAME>.<ARCH>/chroot/后,chroot进入该文件系统执行--second-stage完成配置。
随后mount --bind /dev、拷贝/etc/hosts与/etc/resolv.conf,把src/livecd/chroot/etc/apt/下的 apt 源配置同步进 chroot,并把CODENAME_SUBSTITUTE占位符替换为真实版本代号(src/scripts/build.sh)。
5.3 两阶段 chroot 配置
脚本先后两次进入 chroot 执行配置脚本:
- 第一阶段src/scripts/chroot-steps-part-1.sh:挂载 proc/sys/devpts、apt 索引缓存复用、系统升级、安装 XFCE 桌面与各类工具、针对 Bionic/Focal 32/64 位分别安装 HWE 内核与显卡驱动包等(src/scripts/build.sh);
- 第二阶段src/scripts/chroot-steps-part-2.sh:用
gdebi --non-interactive安装前面构建好的rescuezilla*.deb以及 partclone 系列 deb(src/scripts/chroot-steps-part-2.sh),还原 Ubuntu 仓库的partclone.xfs二进制以兼容新 partclone(src/scripts/chroot-steps-part-2.sh),设置 Plymouth 启动主题为rescuezilla-logo、终端模拟器为xfce4-terminal,最后update-initramfs -u重新生成 initrd(src/scripts/chroot-steps-part-2.sh)。
两次 chroot 之间,脚本会把src/livecd/目录(桌面快捷方式、polkit 策略、主题、grub 配置、plymouth 主题等 FHS 树,见 src/livecd/)整体 rsync 覆盖到 chroot 上,并把 deb 拷入 chroot(src/scripts/build.sh),同时为 GRUB 的 30 多个.po翻译执行msgfmt生成.mo(src/scripts/build.sh)。
5.4 squashfs 根文件系统与压缩级别
根文件系统使用 zstandard 而非默认 gzip 压缩,正式构建用最高压缩级别 19(解压速度与 gzip 相当但压缩率更好);而集成测试构建(IS_INTEGRATION_TEST=true)降级到级别 1 以加快开发迭代(src/scripts/build.sh):
mksquashfs chroot image/casper/filesystem.squashfs -comp zstd -b 1M -Xcompression-level "${COMPRESSION_LEVEL}" -e boot -e /sysIS_INTEGRATION_TEST=true这个开关同时会让镜像内置 SSH 服务与 TCP 查询服务器(netcat)以支持自动化端到端测试,官方公开发布的镜像绝不会开启该开关——这一设计在 src/scripts/build.sh 的注释中有明确说明,配套的使用方法(授权宿主 SSH 公钥 +IS_INTEGRATION_TEST=true make)见 src/integration-test/README.md。
5.5 EFI 引导:签名 shim、GRUB 与 ESP 镜像
这是整个构建中最“特殊”的部分(src/scripts/build.sh):
- 把构建主机的
/usr/lib/shim/shimx64.efi.signed复制为 ISO 内的EFI/BOOT/BOOTx64.EFI(默认 EFI 引导入口,必须是Ubuntu 的shim-signed包,因为它信任 Canonical 的密钥); - 把
/usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed复制为grubx64.efi(Canonical 签名版 GRUB,见 src/scripts/build.sh 注释:Debian 的grub-efi-amd64-signed只信任 Debian 密钥,无法验证 Canonical 签名内核,所以会失败); - 用
dd创建 6 MiB 零文件,mkfs.msdos格式化为 FAT16(UEFI 规范要求可移动介质可用 FAT16/FAT32),再用mcopy把“未打包”的EFI/目录树打进boot/esp.img,形成 ESP 镜像文件; - amd64 镜像中同时携带 i386 版 GRUB EFI(
BOOTIA32.EFI,用于 32 位 UEFI 机器,例如 Bay Trail 平台上 64 位 CPU 配 32 位 UEFI 的情况),以及i386-pc模块支持 El Torito 光驱启动(src/scripts/build.sh)。
5.6 xorrisofs:一份 ISO,三种启动方式
最后用xorrisofs(xorriso 的 mkisofs 兼容模式)把image/目录打成 ISO 9660 镜像(src/scripts/build.sh)。脚本注释里有一段很好的术语速查,值得原文保留:
- ISO9660 是 DVD/CD 常用文件系统(DVD 也常用 UDF);
- 目标是生成一份同时支持U 盘(legacy BIOS/MBR)、EFI(含 Secure Boot)、光驱(El Torito 启动目录)的 ISO9660;
- “EFI 系统通常通过读取 El Torito 格式中的 FAT 镜像文件、把它当作 ESP 来从光盘启动”——这与硬盘上 ESP 是真实分区的做法不同;
- Rock Ridge 提供 POSIX 属性、Joliet 放宽文件名限制、El Torito 是 1995 年的 CD-ROM 启动记录规范;
- ISO9660 文件系统内可以携带 MBR/ESP/GPT 而不妨碍(最多 63 条)El Torito 启动记录,MBR/GPT 存储于文件系统的前 32 KiB。
关键的启动相关参数包括:
--grub2-mbr /usr/lib/grub/i386-pc/boot_hybrid.img # GRUB2 装入 ISO 内置 MBR,支持 legacy BIOS U 盘启动 -eltorito-boot boot/grub/grub.eltorito.bootstrap.img # El Torito 启动镜像(grub-mkimage i386-pc-eltorito 生成) --efi-boot "boot/esp.img" -efi-boot-part --efi-boot-image # 将 ESP 镜像暴露给 UEFI其中grub.eltorito.bootstrap.img由grub-mkimage --format i386-pc-eltorito预先生成,包含 boot/linux/search/fat/iso9660/gfxmenu 等模块(src/scripts/build.sh)。整个 ISO 生成分四步完成(src/scripts/build.sh):第一次xorrisofs用--boot-info-table修改 El Torito 镜像字节 → 挂载 ISO 取出被修改后的引导镜像 → 生成全文件md5sum.txt→ 第二次xorrisofs使校验和包含修改后的二进制。最终产物命名规则为rescuezilla.<ARCH>.<CODENAME>.iso(src/scripts/build.sh),并被移动到build/顶层目录。
六、EFI Secure Boot:为什么 Debian 环境构建的镜像无法安全启动
这是文档中最容易踩坑的知识点,仓库注释与文档说法完全一致:
- Rescuezilla 是Ubuntu 基础的 Live 环境,其内核镜像由 Canonical 签名;
- 若构建主机是 Debian 或非 Ubuntu 包环境,构建出的 ISO 中
grub-efi-amd64-signed来自 Debian 仓库,它只信任Debian 证书; - Secure Boot 开启时,Microsoft 签名 shim → Debian 签名 GRUB 的验证链无法验证Canonical 签名的内核,EFI 启动失败,设备落入 GRUB Rescue Mode;
- 文档指出的解决方案正是“Build ISO with docker”路径:先用容器构造一个符合要求的 Ubuntu 构建环境。文档同时注明,该限制对应上游 issue #59,未来会移除“构建主机必须是 Canonical 包环境”的要求。
源码侧的印证是 src/scripts/build.sh:构建脚本假定构建主机的/usr/lib/shim/与/usr/lib/grub/x86_64-efi-signed/来自 Ubuntu 官方包(shim 信任 Canonical 密钥、grubx64.efi.signed 本身为 Canonical 签名),这正是“构建主机的包环境决定了签名链”的直接体现。
七、使用 Docker 构建:官方发布采用的方式
仓库根目录的 Dockerfile 被纳入版本管理,作用是“为 Live 镜像构建提供一个可复现的主机环境”——由于构建脚本会从构建主机的文件系统直接取用 shim/GRUB 等签名二进制,主机环境的一致性至关重要。官方发布正是基于这一方式构建的,仓库中也保留了相应的 GitHub Actions 工作流(当前快照中的 run-integration-test-suite.yml 用于集成测试流水线)。
Dockerfile 的关键设计:
- 基础镜像由构建参数控制:
ARG CODENAME=noble+FROM ubuntu:${CODENAME},并支持--build-arg覆盖(Dockerfile)。注意注释强调:容器主机的 Ubuntu 版本与所生成镜像的版本相互独立; - apt 源由
src/livecd/chroot/etc/apt/sources.list模板替换CODENAME_SUBSTITUTE/URL_SUBSTITUTE生成,amd64/i386 走archive.ubuntu.com,arm64 走ports.ubuntu.com(Dockerfile); - 按架构条件安装引导签名包:amd64 安装
shim-signed、grub-efi-amd64-signed、grub-efi-amd64-bin、grub-efi-ia32-bin、grub-pc-bin、memtest86+,arm64 安装grub-efi-arm64(Dockerfile)——这正是第六节 Secure Boot 签名链能在任意宿主机上成立的原因; - 其余构建依赖(
debootstrap、squashfs-tools、xorriso、partclone 编译所需的 ntfs-3g/xfsprogs 等)与手工构建时的 apt 列表高度一致(Dockerfile)。
Makefile 提供了一组docker-*辅助目标简化容器操作(Makefile):
make docker-build # docker build --no-cache=true --tag builder.image . make docker-run # 启动特权容器并执行 git safe.directory 配置 make docker-add-safe-directory # 再次信任各 git 子模块目录 make docker-test # 容器内运行 make test make docker-focal / docker-jammy / docker-plucky ... # 容器内构建指定版本 ISO make docker-bash # 交互式 bash 调试容器启动前必须执行 src/scripts/git-add-safe-directory.sh,它为主仓库与各 git 子模块添加safe.directory配置——否则git rev-parse/git describe会因“dubious ownership”拒绝工作,版本号识别(src/scripts/build.sh、src/scripts/build.sh)将失败。
文档同时提醒:Docker 用于开发有相对陡峭的学习成本,如果偏好完全避免 Docker,坚持使用“Build without docker”流程即可。
八、推荐的开发者工作流
文档“Suggested developer workflow”一节给出了按贡献类型选择策略的建议,结合仓库设施可以整理为三条路线:
- 只做前端/应用层改动:完全不需要构建 ISO。直接
make deb产出 deb 包(或make test跑单元测试验证),这是最高效的路径; - 改动 Live 环境组件(grub 配置、桌面、系统服务、partclone 等):按第三节标准流程先构建 ISO → 在 VirtualBox 虚拟机中启动该 ISO(文档指向项目的 VirtualBox 测试环境搭建 wiki;仓库内 src/integration-test/README.md 与 src/integration-test/scripts/configure-virtualbox-vm.sh 提供了配套自动化)→ 在非持久化的 Live 文件系统中直接修改验证 → 满意后把改动文件(如用
scp)导出提交入库 → 重新构建 ISO 迭代测试; - 端到端回归:
make integration-test会初始化一批 VirtualBox VM,执行src/integration-test/tests/下的测试脚本(CentOS MBR+LVM、Windows BIOS/EFI、Ubuntu+Windows 双启动等场景,见 src/integration-test/tests/)。
两个性能预期值得提前知道:即使 deb 包全部命中缓存,从零解包安装仍需要数分钟(“即使在现代计算机上”);缓存机制(pkg.cache/)让重复构建只下载增量包,但每次构建都会完整执行 debootstrap 解包与 chroot 安装流程。
九、常见故障对照
| 现象 | 可能原因与对策(依据) |
|---|---|
This script must be run as root | build.sh的 root 检查(src/scripts/build.sh),请用sudo make <codename> |
debootstrap part 1/2 failed | 宿主机系统自带 debootstrap 版本过旧、没有对应版本代号的脚本;构建脚本实际使用src/third-party/debootstrap子模块中的新版,需确保子模块已git submodule update --recursive(src/scripts/build.sh) |
debootstrap part 2/2 failed | 包缓存存在但不完整,删除pkg.cache/debootstrap.<CODENAME>.<ARCH>/重试(src/scripts/build.sh) |
| 构建旧版本代号时 apt 源 404 | 脚本会自动切换old-releases.ubuntu.com;若两个镜像都失败则退出(src/scripts/lib.sh) |
| git 相关命令报 dubious ownership | 执行 src/scripts/git-add-safe-directory.sh(Docker 场景由make docker-run自动执行) |
| Secure Boot 下启动失败/GRUB Rescue | 构建主机不是 Ubuntu 包环境,改走 Docker 构建(本文第六节) |
小结
Rescuezilla 的 ISO 构建体系可以概括为:Makefile 定义“版本代号 × 架构”的构建目标并先产出 deb 与 partclone/sfdisk 等前置产物 →build.sh用 debootstrap 两阶段法引导 chroot → 两个 chroot 脚本加上src/livecd/静态树装配出完整桌面系统 → mksquashfs(zstd) 压缩根文件系统 → 注入 Canonical 签名 shim/GRUB 与 FAT16 ESP → xorrisofs 一份镜像同时满足 legacy BIOS、El Torito 光驱与 EFI(含 Secure Boot)三种启动。对贡献者而言,前端改动走make deb即可,涉及 Live 环境的改动则建议“构建 ISO → 虚拟机验证 → 导出提交 → 重建”的循环;而无论使用哪种 Linux 发行版,Docker 路径都能保证签名链正确的 Ubuntu 构建环境。
- 桌面应用
- 灾备
【免费下载链接】rescuezilla
The Swiss Army Knife of System Recovery
相关推荐
esptool 安全测试镜像生成指南:Secure Boot 签名与 Flash Encryption 加密镜像的完整制作流程
esptool 安全测试镜像生成指南:Secure Boot 签名与 Flash Encryption 加密镜像的完整制作流程 导读 本文以 esptool 仓
开发工具嵌入式硬件开发Bazzite 定制镜像全指南:从功能特性到 Secure Boot 与自建签名版本
Bazzite 定制镜像全指南:从功能特性到 Secure Boot 与自建签名版本 Bazzite 是基于 Fedora Atomic(Kinoite / S
操作系统OpenCore 自建 Shim 签名链:OpenLinuxBoot + Secure Boot 完整实战指南
OpenCore 自建 Shim 签名链:OpenLinuxBoot + Secure Boot 完整实战指南 导读 本指南基于 OpenCore 仓库 Uti
固件操作系统嵌入式
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考