@tom_doerr: 从零构建自定义 Ubuntu Live ISO 镜像 https://github.com/mvallim/live-custom-ubuntu-from-scratch…
摘要
该 GitHub 仓库提供了从零构建完全自定义 Ubuntu Live ISO 镜像的指南和工具,允许用户预装软件包并配置系统。
查看缓存全文
缓存时间: 2026/05/13 06:42
从头构建定制的 Ubuntu Live ISO https://github.com/mvallim/live-custom-ubuntu-from-scratch… — # mvallim/live-custom-ubuntu-from-scratch 来源: https://github.com/mvallim/live-custom-ubuntu-from-scratch GitHub 星标 (https://github.com/mvallim/live-custom-ubuntu-from-scratch/stargazers) GitHub Fork (https://github.com/mvallim/live-custom-ubuntu-from-scratch/network/members) GitHub 关注者 (https://github.com/mvallim/live-custom-ubuntu-from-scratch/watchers) # 如何从头创建定制的 Ubuntu Live 系统 维护情况 (https://github.com/mvallim/live-custom-ubuntu-from-scratch/graphs/commit-activity) 项目状态 (https://github.com/mvallim/live-custom-ubuntu-from-scratch) GitHub 最后提交 (https://github.com/mvallim/live-custom-ubuntu-from-scratch/commits/master) 许可证: GPL v3 (https://www.gnu.org/licenses/gpl-3.0) Ubuntu 18.04 Bionic (https://releases.ubuntu.com/18.04/) Ubuntu 20.04 Focal (https://releases.ubuntu.com/20.04/) Ubuntu 22.04 Jammy (https://releases.ubuntu.com/22.04/) Ubuntu 24.04 Noble (https://releases.ubuntu.com/24.04/) GitHub Issues (https://github.com/mvallim/live-custom-ubuntu-from-scratch/issues) GitHub Pull Requests (https://github.com/mvallim/live-custom-ubuntu-from-scratch/pulls) 贡献者 (https://github.com/mvallim/live-custom-ubuntu-from-scratch/graphs/contributors) GitHub Release (https://github.com/mvallim/live-custom-ubuntu-from-scratch/releases) 本项目引导您从头构建完全定制的 Ubuntu Linux 版本。它涵盖了创建包含预安装包、配置以及根据您的需要进行定制的脚本的 Live ISO 镜像的步骤。这些步骤将指导您设置环境、配置 chroot、安装软件、修改内核,并最终生成 ISO 镜像。这非常适合那些希望对自己的 Linux 发行版拥有完全控制权的人,无论是用于个人还是专业用途。 ## 要求 * 熟练掌握 Linux shell 命令和脚本编写。 * 拥有足够的磁盘空间和内存来构建 ISO。 ## 步骤 1. 准备环境: 安装必要的依赖项。 2. 创建基础系统: 使用 debootstrap 设置最小化的 Ubuntu 系统。 3. 自定义软件包: 添加/删除软件,配置内核。 4. 生成 ISO: 将系统打包成可引导的 ISO。 ## 作者 * Marcos Vallim - 创始人、作者、开发、测试、文档 - mvallim (https://github.com/mvallim) * Ken Gilmer - 提交者、开发、测试、文档 - kgilmer (https://github.com/kgilmer) 请参阅参与本项目的 贡献者 列表。 ## 使用本教程的方法 * (推荐)逐步遵循下面的说明,以了解如何构建 Ubuntu ISO。 * 在本地检出此仓库后,运行 scripts 目录中的 build.sh 脚本。 * Fork 此仓库并运行 GitHub Action build。这将在您的 GitHub 账户中生成一个 ISO。 build-bionic (https://github.com/mvallim/live-custom-ubuntu-from-scratch/actions/workflows/build-bionic.yml) build-focal (https://github.com/mvallim/live-custom-ubuntu-from-scratch/actions/workflows/build-focal.yml) build-jammy (https://github.com/mvallim/live-custom-ubuntu-from-scratch/actions/workflows/build-jammy.yml) build-noble (https://github.com/mvallim/live-custom-ubuntu-from-scratch/actions/workflows/build-noble.yml) ## 术语 * 构建系统 (build system) - 运行生成 ISO 的构建脚本的计算机环境。 * Live 系统 (live system) - 由 构建系统 生成的、从 Live OS 运行的计算机环境。这也可能被称为 chroot 环境。 * 目标系统 (target system) - 从 Live 系统 完成安装后运行的计算机环境。 ## 前置条件 (GNU/Linux Ubuntu) > [!IMPORTANT] > 请记住非常重要的一点:您生成的版本取决于主机上使用的版本。 > > 示例: > 如果我要从头生成 bionic 版本,则主机必须安装 bionic 或更高版本。 > > | 从头构建版本 | 主机版本 | > |:––––:|:———–:| > | bionic | >= bionic | > | focal | >= focal | > | jammy | >= jammy | > | noble | >= noble | 在 构建系统 中安装我们的脚本所需的软件包。 shell sudo apt-get install \ debootstrap \ squashfs-tools \ xorriso shell mkdir $HOME/live-ubuntu-from-scratch ## 引导并配置 Ubuntu debootstrap 是一个用于生成 OS 镜像的程序。我们将其安装到 构建系统 中,以开始生成我们的 ISO。 * 检出引导环境 shell sudo debootstrap \ --arch=amd64 \ --variant=minbase \ noble \ $HOME/live-ubuntu-from-scratch/chroot \ http://us.archive.ubuntu.com/ubuntu/ > debootstrap 用于从头创建 Debian 基础系统,无需 dpkg 或 apt 的可用性支持。它通过从镜像站点下载 .deb 文件,并仔细将它们解包到一个最终可以 chroot 进入的目录中来实现这一目标。 * 配置外部挂载点 shell sudo mount --bind /dev $HOME/live-ubuntu-from-scratch/chroot/dev sudo mount --bind /run $HOME/live-ubuntu-from-scratch/chroot/run 由于我们将更新和安装软件包(其中包括 grub),这些挂载点在 chroot 环境中是必需的,以便我们能够无错误地完成安装。 ## 定义 chroot 环境 在 Unix 操作系统中,chroot 是一种操作,它更改当前运行进程及其子进程 apparent 根目录。在这种修改后的环境中运行的程序无法命名(因此通常无法访问)指定目录树之外的文件。术语“chroot”可以指 chroot 系统调用或 chroot 包装程序。修改后的环境称为 chroot 监狱。 > 参考:从这里开始,我们将配置 Live 系统。 1. 访问 chroot 环境 shell sudo chroot $HOME/live-ubuntu-from-scratch/chroot 2. 配置挂载点、home 和 locale shell mount none -t proc /proc mount none -t sysfs /sys mount none -t devpts /dev/pts export HOME=/root export LC_ALL=C 这些挂载点在 chroot 环境中是必需的,以便我们能够无错误地完成安装。 3. 设置自定义主机名 shell echo "ubuntu-fs-live" > /etc/hostname 4. 配置 apt sources.list shell cat > /etc/apt/sources.list << EOF deb http://us.archive.ubuntu.com/ubuntu/ noble main restricted universe multiverse deb-src http://us.archive.ubuntu.com/ubuntu/ noble main restricted universe multiverse deb http://us.archive.ubuntu.com/ubuntu/ noble-security main restricted universe multiverse deb-src http://us.archive.ubuntu.com/ubuntu/ noble-security main restricted universe multiverse deb http://us.archive.ubuntu.com/ubuntu/ noble-updates main restricted universe multiverse deb-src http://us.archive.ubuntu.com/ubuntu/ noble-updates main restricted universe multiverse EOF 5. 更新索引软件包 shell apt-get update 6. 安装 systemd shell apt-get install -y libterm-readline-gnu-perl systemd-sysv > systemd 是 Linux 的系统和服务管理器。它提供了激进的并行化能力,使用 socket 和 D-Bus 激活来启动服务,提供按需启动守护进程,使用 Linux 控制组跟踪进程,维护挂载点和自动挂载点,并实现复杂的基于事务的依赖服务控制逻辑。 7. 配置 machine-id 和 divert shell dbus-uuidgen > /etc/machine-id ln -fs /etc/machine-id /var/lib/dbus/machine-id > /etc/machine-id 文件包含在安装或启动期间设置的本地系统的唯一机器 ID。机器 ID 是一个以换行符结尾的、十六进制的、32 字符的小写 ID。从十六进制解码后,这对应于一个 16 字节/128 位的值。此 ID 不能全为零。 shell dpkg-divert --local --rename --add /sbin/initctl ln -s /bin/true /sbin/initctl > dpkg-divert 是用于设置和更新重定向列表的工具。 8. 升级软件包 shell apt-get -y upgrade 9. 安装 Live 系统所需的软件包 shell apt-get install -y \ sudo \ ubuntu-standard \ casper \ discover \ laptop-detect \ os-prober \ network-manager \ net-tools \ wireless-tools \ wpagui \ locales \ grub-common \ grub-gfxpayload-lists \ grub-pc \ grub-pc-bin \ grub2-common \ grub-efi-amd64-signed \ shim-signed \ mtools \ binutils shell apt-get install -y --no-install-recommends linux-generic 10. 图形安装程序 shell apt-get install -y \ ubiquity \ ubiquity-casper \ ubiquity-frontend-gtk \ ubiquity-slideshow-ubuntu \ ubiquity-ubuntu-artwork 由于前一步安装的软件包,下一步将会出现,这将在无需通知或执行任何内容的情况下发生。 1. 配置键盘 2. 控制台设置 11. 安装窗口管理器 shell apt-get install -y \ plymouth-themes \ ubuntu-gnome-desktop \ ubuntu-gnome-wallpapers 12. 安装实用应用程序 shell apt-get install -y \ clamav-daemon \ terminator \ apt-transport-https \ curl \ vim \ nano \ less 13. 安装 Visual Studio Code (可选) 1. 下载并安装密钥 shell curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg install -o root -g root -m 644 microsoft.gpg /etc/apt/trusted.gpg.d/ echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list rm microsoft.gpg 2. 然后更新软件包缓存并使用以下命令安装软件包 shell apt-get update apt-get install -y code 14. 安装 Google Chrome (可选) 1. 下载并安装密钥 shell wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add - echo "deb http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list 2. 然后更新软件包缓存并使用以下命令安装软件包 shell apt-get update apt-get install google-chrome-stable 15. 安装 Java JDK 8 (可选) shell apt-get install -y \ openjdk-8-jdk \ openjdk-8-jre 16. 删除未使用的应用程序 (可选) shell apt-get purge -y \ transmission-gtk \ transmission-common \ gnome-mahjongg \ gnome-mines \ gnome-sudoku \ aisleriot \ hitori 17. 删除未使用的软件包 shell apt-get autoremove -y 18. 重新配置软件包 1. 生成 locales shell dpkg-reconfigure locales 1. 选择 locales 2. 选择默认 locale 2. 配置 network-manager 1. 创建配置文件 shell cat > /etc/NetworkManager/NetworkManager.conf << EOF [main] rc-manager=none plugins=ifupdown,keyfile dns=systemd-resolved [ifupdown] managed=false EOF 2. 重新配置 network-manager shell dpkg-reconfigure network-manager ## 创建镜像目录并填充内容 在设置好 Live 系统 后,我们现在回到 构建环境,并继续创建生成 ISO 所需的文件。 1. 创建目录 shell mkdir -p /image/{casper,isolinux,install} 2. 复制内核镜像 shell cp /boot/vmlinuz-*-generic /image/casper/vmlinuz cp /boot/initrd.img-*-generic /image/casper/initrd 3. 复制 memtest86+ 二进制文件 (BIOS 和 UEFI) shell wget --progress=dot https://memtest.org/download/v7.00/mt86plus_7.00.binaries.zip -O /image/install/memtest86.zip unzip -p /image/install/memtest86.zip memtest64.bin > /image/install/memtest86+.bin unzip -p /image/install/memtest86.zip memtest64.efi > /image/install/memtest86+.efi rm -f /image/install/memtest86.zip ### GRUB 菜单配置 1. 创建 grub 的基础点访问文件 shell touch /image/ubuntu 2. 创建 image/isolinux/grub.cfg shell cat > /image/isolinux/grub.cfg << EOF search --set=root --file /ubuntu insmod all_video set default="0" set timeout=30 menuentry "Try Ubuntu FS without installing" { linux /casper/vmlinuz boot=casper nopersistent toram quiet splash --- initrd /casper/initrd } menuentry "Install Ubuntu FS" { linux /casper/vmlinuz boot=casper only-ubiquity quiet splash --- initrd /casper/initrd } menuentry "Check disc for defects" { linux /casper/vmlinuz boot=casper integrity-check quiet splash --- initrd /casper/initrd } grub_platform if [ "\$grub_platform" = "efi" ]; then menuentry 'UEFI Firmware Settings' { fwsetup } menuentry "Test memory Memtest86+ (UEFI)" { linux /install/memtest86+.efi } else menuentry "Test memory Memtest86+ (BIOS)" { linux16 /install/memtest86+.bin } fi EOF ### 创建清单 接下来,我们创建一个文件 filesystem.manifest 来指定安装在 Live 系统 中的每个软件包及其版本。我们创建另一个文件 filesystem.manifest-desktop,指定将安装在 目标系统 中的文件。一旦 Ubiquity 安装程序完成,它将移除 filesystem.manifest 中指定但未在 filesystem.manifest-desktop 中列出的软件包。 1. 生成清单 shell dpkg-query -W --showformat='${Package} ${Version}\n' | sudo tee /image/casper/filesystem.manifest cp -v /image/casper/filesystem.manifest image/casper/filesystem.manifest-desktop sed -i '/ubiquity/d' /image/casper/filesystem.manifest-desktop sed -i '/casper/d' /image/casper/filesystem.manifest-desktop sed -i '/discover/d' /image/casper/filesystem.manifest-desktop sed -i '/laptop-detect/d' /image/casper/filesystem.manifest-desktop sed -i '/os-prober/d' /image/casper/filesystem.manifest-desktop ### 创建 diskdefines Linux LiveCD 安装光盘上经常发现的 README 文件,例如 Ubuntu Linux 安装 CD;通常命名为“README.diskdefines”并可能在安装期间引用。 1. 创建文件 /image/README.diskdefines shell cat > /image/README.diskdefines << EOF #define DISKNAME Ubuntu from scratch #define TYPE binary #define TYPEbinary 1 #define ARCH amd64 #define ARCHamd64 1 #define DISKNUM 1 #define DISKNUM1 1 #define TOTALNUM 0 #define TOTALNUM0 1 EOF ### 创建镜像 1. 访问镜像目录 shell cd /image 2. 复制 EFI 加载器 shell cp /usr/lib/shim/shimx64.efi.signed.previous isolinux/bootx64.efi cp /usr/lib/shim/mmx64.efi isolinux/mmx64.efi cp /usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed isolinux/grubx64.efi 3. 创建一个包含 EFI 引导加载器的 FAT16 UEFI 启动磁盘镜像 shell ( cd isolinux && \ dd if=/dev/zero of=efiboot.img bs=1M count=10 && \ mkfs.vfat -F 16 efiboot.img && \ LC_CTYPE=C mmd -i efiboot.img efi efi/ubuntu efi/boot && \ LC_CTYPE=C mcopy -i efiboot.img ./bootx64.efi ::efi/boot/bootx64.efi && \ LC_CTYPE=C mcopy -i efiboot.img ./mmx64.efi ::efi/boot/mmx64.efi && \ LC_CTYPE=C mcopy -i efiboot.img ./grubx64.efi ::efi/boot/grubx64.efi && \ LC_CTYPE=C mcopy -i efiboot.img ./grub.cfg ::efi/ubuntu/grub.cfg ) 4. 创建 grub BIOS 镜像 shell grub-mkstandalone \ --format=i386-pc \ --output=isolinux/core.img \ --install-modules="linux16 linux normal iso9660 biosdisk memdisk search tar ls" \ --modules="linux16 linux normal iso9660 biosdisk search" \ --locales="" \ --fonts="" \ "boot/grub/grub.cfg=isolinux/grub.cfg" 5. 组合可引导的 Grub cdboot.img shell cat /usr/lib/grub/i386-pc/cdboot.img isolinux/core.img > isolinux/bios.img 6. 生成 md5sum.txt shell /bin/bash -c "(find . -type f -print0 | xargs -0 md5sum | grep -v -e 'isolinux' > md5sum.txt)" ### 清理 chroot 环境 1. 如果您安装了软件,请确保运行 shell truncate -s 0 /etc/machine-id 2. 移除重定向 shell rm /sbin/initctl dpkg-divert --rename --remove /sbin/initctl 3. 清理 shell apt-get clean rm -rf /tmp/* ~/.bash_history umount /proc umount /sys umount /dev/pts export HISTSIZE=0 exit ## 解除挂载点绑定 shell sudo umount $HOME/live-ubuntu-from-scratch/chroot/dev sudo umount $HOME/live-ubuntu-from-scratch/chroot/run ## 压缩 chroot 之后
相似文章
# 制作 Debian 或 Fedora 持久化 Live 镜像
# 为 Debian、Fedora 和 Ubuntu 创建持久化 Live USB 镜像 Live USB 是快速启动 Linux 环境的绝佳方式,但默认情况下,每次重启后所有更改都会丢失。**持久化存储**功能可以将你的文件、配置和已安装的软件包保留下来。遗憾的是,各发行版对这一功能的实现方式并不统一——每个发行版都有自己的一套做法,内核参数、分区标签和文件系统结构各不相同。 本文将介绍如何通过注入 ext4 分区并利用 OverlayFS 的持久化机制,为 Debian、Fedora 和 Ubuntu 创建持久化 Live USB。此外还会介绍一个不需要重新构建镜像、直接修改 ISO 启动参数的"野路子"字节替换技巧。 --- ## 背景:Live 系统如何实现持久化 大多数现代 Linux Live 系统使用 **OverlayFS** 将只读的压缩根文件系统(通常是 SquashFS)与可写的上层目录叠加在一起。启动时,内核或 initramfs 会在只读层之上挂载一个可写层,使系统看起来像一个完整的可读写文件系统。 持久化功能的原理是:将这个上层目录(overlay upperdir)存放到 USB 驱动器上一个**可写的持久化分区**中,而不是放在内存中。 **挑战在于**:每个发行版寻找持久化分区的方式都不一样: - **Ubuntu/Debian**:使用内核参数 `persistent`,并查找标签为 `casper-rw` 或 `persistence` 的分区 - **Fedora**:使用内核参数 `rd.live.overlay`,并查找标签为 `overlay` 的分区 - **各发行版**的 initramfs 脚本、overlay 目录结构和文件系统要求也各有差异 --- ## 工具准备 ```bash # 安装所需工具 sudo apt install gdisk e2fsprogs util-linux # Debian/Ubuntu sudo dnf install gdisk e2fsprogs util-linux # Fedora ``` 你还需要: - 一个容量足够的 USB 驱动器(建议 16GB 以上) - 目标发行版的 ISO 镜像 - `root` 权限 - (可选)用于字节替换技巧的十六进制编辑器 --- ## 第一步:将 ISO 写入 USB 首先,按照常规方式将 ISO 写入 USB 驱动器: ```bash # 找到你的 USB 设备 lsblk # 写入 ISO(请将 /dev/sdX 替换为实际的设备名) sudo dd if=ubuntu-24.04-desktop-amd64.iso of=/dev/sdX bs=4M status=progress oflag=sync ``` **注意**:`dd` 写入后,分区表反映的是 ISO 内部的布局。ISO 镜像通常不会占满整个 USB 驱动器,末尾会留有大量未使用的空间——我们将利用这部分空间创建持久化分区。 --- ## 第二步:添加持久化分区 ISO 写入后,USB 末尾应有未分配的空间。我们将在这里创建一个新的 ext4 分区。 ### 查看当前分区布局 ```bash sudo gdisk -l /dev/sdX ``` 记下最后一个分区的结束扇区,新分区将从下一个扇区开始。 ### 创建新分区 ```bash sudo gdisk /dev/sdX ``` 在 `gdisk` 交互界面中: ``` Command: n # 新建分区 Partition number: (接受默认值) First sector: (接受默认值,即紧接上一分区之后) Last sector: (接受默认值,使用全部剩余空间;或指定大小,如 +8G) Hex code: 8300 # Linux 文件系统 Command: w # 写入并退出 ``` ### 格式化分区 这是关键步骤——**分区标签必须与发行版的 initramfs 脚本所期望的完全一致**。 #### Ubuntu(casper) ```bash sudo mkfs.ext4 -L casper-rw /dev/sdX3 ``` Ubuntu 的 `casper` initramfs 脚本会扫描所有已挂载的设备,查找标签为 `casper-rw` 的分区。 #### Ubuntu(较新版本使用 persistence) 某些 Ubuntu 版本和 Ubuntu 衍生版使用不同的标签: ```bash sudo mkfs.ext4 -L persistence /dev/sdX3 ``` 使用 `persistence` 标签时,还需要在分区根目录创建一个配置文件: ```bash sudo mount /dev/sdX3 /mnt echo "/ union" | sudo tee /mnt/persistence.conf sudo umount /mnt ``` #### Debian(live-boot) ```bash sudo mkfs.ext4 -L persistence /dev/sdX3 # 挂载并创建配置文件 sudo mount /dev/sdX3 /mnt echo "/ union" | sudo tee /mnt/persistence.conf sudo umount /mnt ``` Debian 的 `live-boot` 包需要 `persistence.conf` 文件来指定哪些目录应该被持久化。`/ union` 表示使用 union 挂载方式持久化整个根目录。 #### Fedora(dracut) ```bash sudo mkfs.ext4 -L overlay /dev/sdX3 ``` Fedora 使用 `dracut` 而非 `casper`,其持久化机制完全不同。`dracut` 的 `dmsquash-live` 模块会查找标签为 `overlay` 的分区。 --- ## 第三步:修改内核启动参数 创建好分区后,还需要在启动参数中告诉内核(或 initramfs)启用持久化功能。有三种方式可以实现。 ### 方式一:在启动菜单中手动编辑(适合测试) 启动时,在 GRUB 或 syslinux 菜单处按 `e`(GRUB)或 `Tab`(syslinux),然后手动添加参数: **Ubuntu/Debian:** ``` persistent ``` **Fedora:** ``` rd.live.overlay=LABEL=overlay rd.live.overlay.overlayfs=1 ``` ### 方式二:修改 USB 上的配置文件(推荐) 如果 USB 上的 EFI 或 syslinux 分区可写,可以直接修改配置文件。 挂载 EFI 分区: ```bash sudo mount /dev/sdX2 /mnt ``` 找到启动配置文件: ```bash find /mnt -name "grub.cfg" -o -name "isolinux.cfg" -o -name "*.conf" | head -20 ``` **对于 Ubuntu 的 grub.cfg:** ```bash sudo nano /mnt/boot/grub/grub.cfg ``` 找到 `linux` 行,添加 `persistent`: ``` linux /casper/vmlinuz boot=casper persistent quiet splash --- ``` **对于 Fedora 的 grub.cfg:** ``` linux /images/pxeboot/vmlinuz rd.live.image rd.live.overlay=LABEL=overlay rd.live.overlay.overlayfs=1 quiet ``` ### 方式三:字节替换技巧(无需重新构建 ISO) 这是最"野路子"的方法,但在 USB 上的文件系统为只读时(如某些混合 ISO 镜像)非常有用。其原理是:直接在 ISO/USB 设备的原始字节层面,将现有的内核参数替换为新的参数。 **前提条件**:替换后的字符串长度必须与原字符串**完全相同**,不足的部分用空格或空字节填充。 #### 查找参数字符串 ```bash # 在设备中搜索目标字符串 sudo grep -c "boot=casper" /dev/sdX # 确认字符串存在 sudo grep -oba "boot=casper" /dev/sdX | head -5 ``` `grep -oba` 会输出字符串的字节偏移量: ``` 12345678:boot=casper ``` #### 使用 Python 执行字节替换 ```python #!/usr/bin/env python3 """ ISO/USB 内核参数字节替换工具 警告:直接修改块设备——操作前务必备份! """ import sys device = "/dev/sdX" # 原始字符串(长度必须与替换字符串一致) old_param = b"boot=casper" # 新字符串(添加 persistent 参数) new_param = b"boot=casper persistent" # 注意:两者长度不同,需要调整 # 更实用的示例:在现有参数中添加 'persistent' # 找一个可以安全覆盖的较长字符串 old_string = b"boot=casper quiet splash" new_string = b"boot=casper persistent " # 用空格填充,保持长度相同 assert len(old_string) == len(new_string), "字符串长度必须相同!" print(f"原始字符串:{old_string}") print(f"替换字符串:{new_string}") print(f"长度:{len(old_string)} 字节") with open(device, "r+b") as f: data = f.read() count = data.count(old_string) print(f"找到 {count} 处匹配") if count == 0: print("未找到目标字符串,请检查参数") sys.exit(1) # 替换所有匹配项 new_data = data.replace(old_string, new_string) f.seek(0) f.write(new_data) print("替换完成!") ``` > ⚠️ **警告**:直接写入块设备极具风险。操作前务必确认设备名称,并做好备份。 #### 更安全的替换方式(按偏移量操作) ```python #!/usr/bin/env python3 """按偏移量进行精确字节替换""" import subprocess import sys device = sys.argv[1] if len(sys.argv) > 1 else "/dev/sdX" old_bytes = b"boot=casper quiet" new_bytes = b"boot=casper persi" # 长度相同 # 使用 grep 查找偏移量 result = subprocess.run( ["grep", "-oba", old_bytes.decode(), device], capture_output=True, text=True ) offsets = [] for line in result.stdout.strip().split('\n'): if ':' in line: offset = int(line.split(':')[0]) offsets.append(offset) print(f"在以下偏移量找到匹配:{offsets}") with open(device, "r+b") as f: for offset in offsets: f.seek(offset) found = f.read(len(old_bytes)) print(f"偏移量 {offset} 处:{found}") # 确认后再写入 confirm = input("是否替换?(y/N) ") if confirm.lower() == 'y': f.seek(offset) f.write(new_bytes) print(f"已替换偏移量 {offset} 处的内容") print("操作完成") ``` --- ## 各发行版详细说明 ### Ubuntu(casper) Ubuntu 使用 `casper` 包处理 Live 系统启动。持久化功能的相关代码位于 `/usr/share/initramfs-tools/scripts/casper` 及其模块目录中。 **工作原理:** 1. casper 在启动时扫描所有块设备 2. 查找标签为 `casper-rw` 的分区,或包含 `persistence.conf` 的 `persistence` 分区 3. 使用 OverlayFS 将其挂载为上层目录 4. 将合并后的文件系统作为根目录挂载 **完整配置示例:** ```bash # 1. 写入 ISO sudo dd if=ubuntu-24.04-desktop-amd64.iso of=/dev/sdX bs=4M status=progress # 2. 创建持久化分区 sudo gdisk /dev/sdX # n -> 默认 -> 默认 -> 默认 -> 8300 -> w # 3. 格式化(使用 casper-rw 标签) sudo mkfs.ext4 -L casper-rw /dev/sdX3 # 4. 修改启动参数(如果 EFI 分区可写) sudo mount /dev/sdX2 /mnt/efi sudo sed -i 's/boot=casper/boot=casper persistent/g' /mnt/efi/boot/grub/grub.cfg sudo umount /mnt/efi ``` ### Debian(live-boot) Debian 的 Live 系统使用 `live-boot` 包,其配置方式与 Ubuntu 的 casper 类似,但有一些重要区别。 **工作原理:** 1. live-boot 查找标签为 `persistence` 的分区 2. 读取分区根目录的 `persistence.conf` 文件 3. 根据配置文件的指令创建 OverlayFS **`persistence.conf` 格式:** ``` # 持久化整个根目录(最常用) / union # 或者只持久化特定目录 /home union /etc union ``` **完整配置示例:** ```bash # 1. 写入 ISO sudo dd if=debian-12.0.0-amd64-live-gnome.iso of=/dev/sdX bs=4M status=progress # 2. 创建并格式化持久化分区 sudo gdisk /dev/sdX # 新建分区 sudo mkfs.ext4 -L persistence /dev/sdX3 # 3. 创建 persistence.conf sudo mount /dev/sdX3 /mnt echo "/ union" | sudo tee /mnt/persistence.conf sudo umount /mnt # 4. 修改启动参数(添加 persistence 参数) # 在 GRUB 菜单中手动添加,或修改配置文件 ``` **Debian 需要的内核参数:** ``` persistence persistence-label=persistence ``` 或仅使用: ``` persistence ``` (`live-boot` 会自动查找 `persistence` 标签的分区) ### Fedora(dracut + dmsquash-live) Fedora 的 Live 系统机制与 Debian/Ubuntu 完全不同,使用 `dracut` 和 `dmsquash-live` 模块。 **工作原理:** 1. dracut 的 `dmsquash-live` 模块处理 SquashFS 根文件系统的挂载 2. 通过 `rd.live.overlay` 参数指定 overlay 分区 3. 使用 device mapper 而非直接使用 OverlayFS(取决于版本) **Fedora 持久化分区设置:** ```bash # 1. 写入 ISO sudo dd if=Fedora-Workstation-Live-x86_64-39.iso of=/dev/sdX bs=4M status=progress # 2. 创建持久化分区 sudo gdisk /dev/sdX # 新建分区 sudo mkfs.ext4 -L overlay /dev/sdX4 # 注意:Fedora 有更多默认分区 # 3. 修改 GRUB 参数(添加以下内容) # rd.live.overlay=LABEL=overlay rd.live.overlay.overlayfs=1 ``` **Fedora 所需的内核参数:** ``` rd.live.image rd.live.overlay=LABEL=overlay rd.live.overlay.overlayfs=1 ``` 如需重置 overlay(丢弃所有持久化更改),可添加: ``` rd.live.overlay.reset ``` --- ## 故障排查 ### 持久化功能不生效 **检查分区标签:** ```bash sudo blkid /dev/sdX3 # 应显示:LABEL="casper-rw" 或 LABEL="persistence" 或 LABEL="overlay" ``` **检查内核参数:** ```bash cat /proc/cmdline # 应包含 persistent(Ubuntu/Debian)或 rd.live.overlay(Fedora) ``` **检查 Live 系统日志:** ```bash # Ubuntu/Debian dmesg | grep -i "casper\|persist\|overlay" journalctl -b | grep -i "live\|persist" # Fedora dmesg | grep -i "overlay\|live" ``` ### USB 重启后无法识别 部分 BIOS/UEFI 对 GPT 磁盘(而非混合 MBR)的兼容性存在问题。可尝试以下方法: ```bash # 混合 MBR 写入(如有必要) sudo gdisk /dev/sdX # 进入 expert 菜单:x # 创建混合 MBR:h # 按提示操作,选择前 3 个分区 ``` ### Fedora overlay 分区未找到 Fedora 的 dracut 有时在识别 overlay 分区时存在时序问题。可尝试添加以下参数: ``` rd.live.overlay=LABEL=overlay rootflags=noatime ``` 或直接使用设备路径代替标签: ``` rd.live.overlay=/dev/sdb4 ``` ### 分区空间已满 ```bash # 查看持久化分区使用情况(在 Live 系统中执行) df -h /run/live/persistence/sdb3 # Debian/Ubuntu df -h /run/overlayfs # Fedora # 清理 apt 缓存 sudo apt clean sudo apt autoremove ``` --- ## 局限性与注意事项 ### 内核更新 内核更新是持久化 Live 系统的一大痛点。由于内核文件存储在只读的 ISO 部分,常规的 `apt upgrade` 或 `dnf upgrade` 无法更新内核。可以安装内核,但新内核的 GRUB 条目不会生效,因为 GRUB 配置同样位于只读区域。 **解决方法**:手动将新内核文件复制到可写的 EFI 分区,并更新 GRUB 配置——但这需要额外的手动操作,本文不作详述。 ### 性能 持久化 overlay 层会带来一定的性能开销,因为每次文件系统操作都需要经过 OverlayFS 层。对于写入密集型任务,建议使用高速 USB 3.0 驱动器。 ### 跨发行版兼容性差 如前所述,各发行版之间缺乏标准化: | 发行版 | initramfs | 参数 | 分区标签 | 配置文件 | |--------|-----------|------|----------|----------| | Ubuntu(旧版)| casper | `persistent` | `casper-rw` | 不需要 | | Ubuntu(新版)| casper | `persistent` | `persistence` | 需要 | | Debian | live-boot | `persistence` | `persistence` | 需要 | | Fedora | dracut | `rd.live.overlay` | `overlay` | 不需要 | 这意味着:同一个 USB 驱动器无法同时为多个发行版提供持久化支持(至少不能轻松实现)。 ### 字节替换技巧的局限性 字节替换方法虽然便捷,但存在一些限制: - 新旧字符串长度必须相同 - 如果参数被压缩或哈希校验,替换会失败 - 某些 GRUB 版本会对配置文件进行校验,替换后可能无法启动 - UEFI Secure Boot 环境下可能遇到额外的校验问题 --- ## 总结 为不同的 Linux 发行版创建持久化 Live USB 是完全可行的,但因为缺乏统一标准,每个发行版都需要单独对待: 1. **Ubuntu** 使用 casper,需要 `casper-rw` 或 `persistence` 标签,以及 `persistent` 内核参数 2. **Debian** 使用 live-boot,需要 `persistence` 标签、`persistence.conf` 文件,以及 `persistence` 内核参数 3. **Fedora** 使用 dracut,需要 `overlay` 标签,以及 `rd.live.overlay` 内核参数 字节替换技巧为修改只读 ISO 的启动参数提供了一种无需重新构建镜像的快捷方式,但使用时需格外谨慎。 希望 Linux 社区未来能够在 Live 系统持久化功能上实现更好的标准化——但就目前而言,了解这些底层细节对于让持久化 Live USB 正常工作仍然是必要的。
codecrafters-io/build-your-own-x
一个精选的GitHub仓库,汇集了从零开始重建各种技术的逐步指南,从3D渲染器到神经网络,旨在通过创作进行深度学习。
完全在浏览器中的容器构建
一个完全在浏览器中使用客户端代码构建容器的Web应用程序,展示了自定义容器工具的强大功能。用户可以选择基础镜像、运行Shell脚本,并将生成的镜像导出为tar文件。
@tom_doerr:基于畅销指南的系统设计面试笔记 https://github.com/liquidslr/system-design-notes…
一个 GitHub 仓库,包含基于 Alex Xu 畅销书的综合系统设计面试笔记,涵盖扩展性、一致性哈希和分布式系统等主题。
rasbt/LLMs-from-scratch
该仓库提供开源代码,用于从零开始构建、预训练和微调一个类似GPT的大型语言模型,是Sebastian Raschka同名书籍的官方代码配套。