从零打造自己的Linux LiveCD:原理、实操与避坑指南
2026/9/17 7:57:45 网站建设 项目流程

凌晨两点被电话叫醒,说生产环境一台机器起不来,数据倒是没丢,可系统卡在内核 panic。等我远程上去一看,手头既没有安装盘,也没有现成的维护系统,那一刻是真的体会到什么叫“书到用时方恨少”。后来我养成了一个习惯:每配置好一台 Linux 环境,就顺手把它做成 LiveCD/LiveUSB 镜像。这个习惯救过我很多次——系统密碼忘了、引导坏了、内核升级翻车、甚至要给好几台配置完全相同的机器批量装机,一张自制的 Live 系统就能全部搞定。

这篇文章就以“把 Linux 系统做成 Livecd”为主线,从原理到实操再到避坑,把整条路走一遍。不管你是运维、嵌入式工程师,还是喜欢折腾系统的玩家,看完都能按步骤做出一个属于你自己的可启动镜像。

1. LiveCD 到底能拿来干什么,值得不值得自己动手做

很多人一听到 LiveCD 就觉得是远古产物,毕竟现在装系统都用 U 盘、用网络 PXE,光盘早就退环境了。但 LiveCD 这个词在技术圈里其实已经泛指“可启动的 Live 镜像”,载体是光盘还是 U 盘根本不重要,关键在“Live”两个字:不安装在硬盘上,插上就能跑,跑完不留下痕迹。

我自己用下来,Live 镜像最核心的几个使用场景是这样的:

  • 系统救援:root 密码忘了、grub 引导坏了、fstab 写错导致开机失败,这些情况都可以用 Live 系统启动后挂载硬盘修复。我清理过不少忘记密码的机器,流程就是 Live 起来、chroot 进原系统、passwd 重置,十分钟搞定。
  • 批量部署:给十几台配置一样的设备装系统,不用一台一台按安装向导点到底。提前定制好一个 Live 镜像,里面装好全部软件、配好网络和优化项,开机后自动执行部署脚本即可。
  • 硬件测试与演示:在不确定目标机器硬件环境的情况下,Live 系统是最安全的试金石。比如给客户演示软件、测试某台机器的内存和硬盘健康状况,都不会污染本机系统。
  • 嵌入式与离线环境:很多嵌入式设备没有固定硬盘,或者需要在产线上快速刷写系统,Live 镜像加一个自动化脚本就是一套轻量产线工具。
  • 保留当前“顺手”的环境:这是我最常做的一件事。把某个阶段配置得非常顺手的系统打包成镜像,哪怕后面把系统搞崩了,也能随时找回那个“顺手”的状态。

这就是自己动手做 LiveCD 的意义所在。官方发行版给的安装镜像,里面除了基础系统啥也没有;但是你自己做出来的 Live 系统,包含的是你需要的驱动、软件、配置、脚本和习惯。换句话说,官方镜像是“毛坯房”,自己做的是“拎包入住”。

在动手之前,还有几个概念需要分清,否则后面很容易绕晕:

  • LiveCD / LiveUSB:只读介质上运行的完整操作系统,关掉之后所有改动消失。
  • Live 系统持久化:允许把改动保存到一个独立分区,重启后仍在,这是 Live 系统的一个重要变体,后面定制章节会专门讲。
  • 救援模式:某些发行版安装盘里带的一个最小化维护环境,功能比 Live 系统轻量得多,本质上是安装程序的一个附属工具。
  • 可引导镜像:泛指任何能启动的镜像文件,包括安装镜像、Live 镜像、救援镜像。

搞清楚这些之后,下面就要进入真正的核心了:一个 Live 系统到底是怎么被引导起来的。

2. Live 系统的启动链路:从固件到根文件系统的完整流程

这一节我尽量讲得仔细一点。因为网上很多教程直接就给命令,照着敲能出结果,但一旦遇到问题就完全不知道从哪里排查。理解了启动链路,出问题你才能自己定位。

2.1 内核、initramfs 与根文件系统的三角关系

任何 Linux 系统启动,内核和根文件系统是缺一不可的。正常硬盘安装的系统里,内核在/boot/vmlinuz-*,根文件系统在一个真实分区上,比如/dev/sda2。开机时引导加载器把内核读进内存,内核挂载这个分区作为根目录,启动接管。

Live 系统不一样,它没有“真实”的根分区,需要先加载 initramfs(也叫 initrd),在内存里搭一个临时的根环境,再由这个临时环境去找到 Live 介质、加载必要的驱动、挂载压缩的根文件系统,最后才切到真正的系统根目录。

initramfs 在 Live 启动中承担的角色,相当于一个“中转站”。内核只负责最基本的硬件初始化和把 initramfs 解压到内存,剩下所有和“找到 Live 系统”相关的活,都是 initramfs 里的脚本干的。所以 Live 制作的关键之一,就是你的 initramfs 里必须包含正确的启动钩子脚本,这也是后面用现成工具而不是完全手搓的一个重要原因。

2.2 squashfs、overlayfs 和 tmpfs:Live 系统的三大支柱

先看三个组件的分工:

  • squashfs:一个只读、高压缩的 Linux 文件系统。Live 系统把整个根文件系统打成一个.squashfs文件放在介质上,启动时挂载它。
  • tmpfs:基于内存的临时文件系统。Live 系统启动后,需要一个可写的目录让程序创建临时文件,这个目录通常就是 tmpfs。
  • overlayfs:一个联合文件系统,可以把一个只读层和一个可写层合并成一个看起来可读写的目录。Live 系统把 squashfs 作为 lowerdir,tmpfs 作为 upperdir,合起来就是完整的根目录。

用一个生活化的类比来解释:squashfs 就像一本印刷好的书,内容固定、不能涂改;tmpfs 像一沓便利贴,想写什么写什么,但关机就没了;overlayfs 则像一块透明玻璃板压在书页上,你用笔在玻璃板上写字,看起来字就在书页上,但书本身一点没变。Live 系统运行过程中所有的“写入”,其实都写在了便利贴(tmpfs)上,关机直接扔掉,所以 Live 系统能保持每次启动都是原始状态。

这个设计有两个很明显的优点:

  • 体积小:整个系统经过压缩,一个几个 GB 的安装系统压缩成镜像后可能只有一半大小,适合放在 U 盘或光盘上。
  • 稳定性高:只读层不会因为异常断电被写坏,所以 Live 介质寿命很长。

2.3 引导加载器与 BIOS/UEFI 双模式

现在的新机器基本都是 UEFI 启动,但存量设备里还有大量 BIOS 老机器。自己制作 Live 镜像时,如果只做了一种引导方式,换台机器就可能启动不了。所以成品镜像最好同时支持两种模式:

  • BIOS 模式:用 ISOLINUX/SYSLINUX 引导,读取 isolinux.cfg 配置启动参数。
  • UEFI 模式:用 GRUB2 引导,读取 grub.cfg 配置启动参数。

一个 ISO 镜像里同时放两套引导文件,刻录或写入 U 盘后,固件会自动选择对应的模式。这也是我推荐用xorrisogrub-mkrescue这类工具生成镜像的原因,它们能一次性处理双引导。自己手动拼镜像的话,很容易漏掉某个架构的引导文件,而且很难排查。

启动参数(kernel command line)也是 Live 系统的灵魂。常见的有:

  • root=live:LABEL=xxx:指定 Live 介质的位置,其中 xxx 是卷标。
  • toram:把整个 Live 系统加载进内存再运行,跑起来之后介质可以拔掉,速度也快很多,代价是内存占用大。
  • persistence:启用持久化,把改动保存到持久化分区。

到这里,Live 系统的基本原理已经清楚了。下面进入选型环节,聊聊用哪种姿势把它做出来。

3. 方案选型:四种常见路线,哪种适合你

做 Live 镜像的路线没有标准答案,关键看你的目标和动手能力。我按从“省事”到“硬核”排一个序,你们可以自己对号入座。

3.1 路线一:直接改造发行版官方 Live 镜像

很多主流发行版本来就有官方 Live 镜像,比如 Ubuntu、Kali、Debian 的 Live 版本。你不需要从头做,只需要把官方镜像里的.squashfs文件解包、加入自己的软件和配置、再重新打包。

这个路线的优点在于省事,底层的引导配置都已经弄好了,你只需要动根文件系统。缺点是官方 Live 镜像的软件集是固定的,加太多东西很容易超过介质容量限制,而且解包重打包过程中容易出现权限和链接文件问题。

适合场景:只需要往 Kali 或 Ubuntu Live 里塞几个工具脚本,不想折腾底层的人。

3.2 路线二:用 linux-live 工具包把当前系统压成镜像

这条路线是我个人最常用的,也是下面实操重点讲的。核心思路很简单:在当前正在运行的 Linux 系统上执行一个脚本,它会把除了/proc/sys/dev等虚拟文件系统之外的整个根目录打包成 squashfs,然后配合预设的 initramfs 和引导文件生成 ISO。

优点非常明显:

  • 打包出来的就是当前这个系统的完整状态,包括你装过的软件、做过的配置、创建的用户,全都原样保留。
  • 脚本已经处理好 initramfs 和引导配置,出错几率低。
  • 适合“环境复制”场景,比如我把某个配置好的工作环境保留成镜像,随时恢复。

缺点也有:打包过程会占用大量临时磁盘空间,生成大镜像后引导时间相对长,而且它是“通用方案”,对特殊硬件(比如各种显卡、网卡固件)不会自动针对性地做优化。但总体而言,这是性价比最高的方案。

3.3 路线三:用发行版构建工具从零定制

Debian/Ubuntu 系有 live-build,Arch 系有 archiso。这类工具理论上可以定制出一个完全干净的 Live 系统,想加什么包就加什么包,最终产物是标准的发行版 Live 镜像。

这条路线适合要做成“一个自定义发行版”的人,或者嵌入式产品。但学习曲线非常陡,需要深刻理解 apt 源、依赖关系、引导配置、hooks 脚本等等。我见过不少人用 live-build 折腾了一周,最后做出来的镜像还不如直接用路线二省心。

3.4 路线四:基于 debootstrap/arch-chroot 手工构建

完全不依赖现成工具,用手工命令把根文件系统 chroot 出来,然后手动配置引导、打包 squashfs 文件。这是最硬核的方式,也是理解 Linux 系统结构的最快路径,但对新手非常不友好。

我总结了一个对比表,方便选择:

维度改造官方 Livelinux-live 打包当前系统live-build/archiso手工构建
上手难度很高
可定制性中等中等偏上最高
是否能保留当前环境
适合场景快速工具盘环境备份/批量克隆定制发行版学习/嵌入式
出错风险中等

如果你问我的推荐,我会说:80% 的场景用路线二就够了,剩下的用路线一或者路线三。下面我就把路线二的完整实操过程展开讲。

4. 动手实操:把当前 Linux 系统打包成可启动 ISO

开始之前先交代我的实验环境,方便你对照:

  • 发行版:Debian 12 / Ubuntu 22.04 均可(下面命令通用)
  • 内核版本:5.15+
  • 磁盘剩余空间:至少 10GB(这个数字后面解释怎么算出来的)
  • 目标介质:4GB 以上 U 盘

4.1 前期准备:装工具、算空间、关掉干扰项

先安装制作过程中需要的工具:

sudo apt update sudo apt install -y squashfs-tools rsync mkisofs xorriso isolinux syslinux-common

整理一下每个工具的用途:

  • squashfs-tools:提供mksquashfs命令,用来压缩根文件系统。
  • rsync:打包时同步根目录文件,保留权限、链接、属主。
  • mkisofsxorriso:把打包好的文件和引导文件制作成 ISO。
  • syslinux:提供 BIOS 引导所需的 isolinux.bin。
  • isolinux包:提供 isolinuxcfg 模板。

空间的估算有个公式:根目录实际使用量加上 1.5GB 左右的余量,就是打包过程中需要的临时空间。比如根目录用了 6GB,你最好留出 8–10GB 的剩余空间,因为脚本要把文件先复制成中间结构,再压缩成 squashfs,中间那一步占用的是原始大小。

另外一个容易被忽略的准备工作:关掉会影响打包的服务和进程。比如 Docker 容器数据量大的话,/var/lib/docker会被原样打包进去,体积直接爆炸;某些数据库服务运行中的缓存也会被复制。我的习惯是制作镜像前先停掉不必要的服务,并清理包管理器的缓存:

sudo apt clean sudo journalctl --vacuum-size=50M sudo rm -rf /var/tmp/*

这些操作能显著减小镜像体积,也能减少打包时因文件不断变化导致的不一致问题。

4.2 下载并运行 linux-live 脚本

linux-live 是一个开源工具包,本质是一个 shell 脚本集合。下载后解压到/opt下:

sudo git clone https://github.com/Tomas-M/linux-live.git /opt/linux-live

不需要安装,直接进目录运行:

cd /opt/linux-live sudo ./build

脚本会做以下几件事:

  1. 收集当前内核版本,准备对应的 vmlinuz 和 initramfs。
  2. 用 rsync 把根目录(排除虚拟文件系统、临时目录等)同步到工作目录。
  3. 用 mksquashfs 把同步好的根目录压缩成rootfs.squashfs
  4. 在指定输出目录生成完整的可引导目录结构。

这个过程会比较久,取决于你的根目录大小和 CPU 性能。如果根目录有 10GB,机械硬盘环境下可能要二三十分钟,SSD 会快很多。看到类似下面的输出,说明打包进行中:

Copying /etc ... Copying /usr ... Copying /var ... ... Creating squashfs image...

整个过程中不要中断,否则工作目录里会有残留,需要清理后重新来。

4.3 生成 ISO 镜像

脚本跑完后,在/opt/linux-live/output(不同版本路径可能有差异)下能看到类似linux-live.iso的成品。很多时候版本号在文件名里,比如linux-live-6.5.7.iso,直接重命名成你自己方便记的名字就行。

cd /opt/linux-live/output sudo mv linux-live-*.iso my-custom-live.iso

如果你在前面步骤没有自动生成 ISO,也可以手动执行生成命令。下面是一个典型的命令示例:

sudo xorriso -as mkisofs \ -o my-custom-live.iso \ -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin \ -c isolinux/boot.cat \ -b isolinux/isolinux.bin \ -no-emul-boot \ -boot-load-size 4 \ -boot-info-table \ -eltorito-alt-boot \ -e boot/grub/efi.img \ -no-emul-boot \ -isohybrid-gpt-basdat \ -V "MYLIVE" \ /opt/linux-live/iso-root

这里多解释一下几个关键参数:

  • -isohybrid-mbr:让 ISO 同时具备硬盘引导能力,这样写进 U 盘后,既能当光盘也能当硬盘启动。
  • -b isolinux/isolinux.bin:指定 BIOS 模式的引导文件。
  • -eltorito-alt-boot -e boot/grub/efi.img:指定 UEFI 模式的引导镜像。
  • -V "MYLIVE":设置卷标。这个卷标必须和引导配置里的卷标一致,否则会找不到 Live 介质。

4.4 虚拟机先验证,再写 U 盘

生成 ISO 后,我强烈建议先在虚拟机里验证,不要直接拿实机试。虚拟机验证通过,至少能排除 90% 的镜像制作问题。

目前我用得最多的是 VirtualBox 和 QEMU。QEMU 一条命令就能测:

qemu-system-x86_64 -cdrom my-custom-live.iso -m 2048 -boot d

注意内存要分配得足够,Live 系统启动时要把 squashfs 挂载上,内存太小会直接启动失败,建议至少给 2GB。

验证通过后,写入 U 盘。U 盘数据会被清空,提前确认盘中没有重要文件:

sudo dd if=my-custom-live.iso of=/dev/sdX bs=4M status=progress oflag=sync

/dev/sdX替换成你的 U 盘设备名,注意千万不要写错,/dev/sda写错就是灾难。用lsblk先看清楚设备名:

lsblk

写完后就可以插到目标机器上启动。如果启动不了,优先检查启动顺序和固件引导模式,这两项是实机测试最常见的坑。

5. 成品定制:引导菜单、默认账号、自动配置和持久化

基础的 Live 镜像已经能跑了,但光能跑还不够。我实际使用中,几乎每次都要对成品做进一步定制,下面这几个方向是最高频的定制需求。

5.1 修改引导菜单,加入多个启动项

默认的引导菜单通常只有“启动 Live 系统”一个选项。我习惯再加两三项:

  • 正常启动
  • 启用 toram(全部加载进内存)
  • 启用持久化(如果插了持久化分区)
  • 内存测试

修改位置根据引导方式区分:

  • BIOS 模式:编辑/opt/linux-live/iso-root/isolinux/isolinux.cfg
  • UEFI 模式:编辑/opt/linux-live/iso-root/boot/grub/grub.cfg

比如 isolinux.cfg 里添加一个 toram 启动项:

LABEL toram MENU LABEL Live System (toram) KERNEL /boot/vmlinuz INITRD /boot/initramfs APPEND root=live:LABEL=MYLIVE toram quiet

注意两套配置文件里的卷标必须一致,这就是前面说的-V "MYLIVE"里的值。如果这里写错,启动时会卡在等待 Live 介质的地方。我踩过这个坑,排查了很久才发现是大小写不一致。

5.2 预设默认账号和开机自启脚本

由于 Live 系统每次启动都是全新的,直接改/etc/passwd里用户密码,重启后又会回到初始状态。所以正确的做法是:在打包之前,把系统中的用户配置改好,再执行打包。这样打包进 squashfs 里面的就是配置好的状态。

我的习惯是创建一个专用账号,用于日常使用:

sudo useradd -m -s /bin/bash liveuser echo 'liveuser:livepassword' | sudo chpasswd

打包完成后,这个账号和默认密码就是 Live 系统的“出厂设置”。

如果你需要在 Live 启动后自动执行脚本,有两个位置可以放:

  • /etc/rc.local:经典的启动后脚本,适合简单的命令。
  • systemd service:适合管理需要等待网络就绪等复杂场景。

比如我想让 Live 系统开机后自动获取 IP 并打印到屏幕,可以写一个 systemd 服务,让它After=network-online.target,然后执行ip addr show。这类定制在批量部署场景中特别有用。

5.3 持久化:让 Live 系统“记住”你的改动

Live 系统每次重启还原,这是特性也是缺点。有些场景你希望它能保存配置、日志或者新增的软件,持久化就是干这个用的。

持久化的实现原理还是 overlayfs:把可写层从内存 tmpfs 换成 U 盘上的一个分区。启动时系统会查找标记为persistence的分区,把它作为 upperdir 使用。

配置步骤:

  1. U 盘分出一个独立分区,不用太大,4GB 足够日常用。
  2. 给该分区设置卷标:
sudo e2label /dev/sdX2 persistence
  1. 在引导配置里给内核添加persistence参数。

这样启动后你在系统里的/home/etc等目录的改动,会保存到持久化分区的 overlay 层里。要注意的是,不是所有目录都被持久化,通常默认只覆盖整个根目录的改动,但每次关机前必须通过正常方式关机,让 overlay 正确落盘,直接拔电有损坏分区的风险。

5.4 压缩率与镜像体积的取舍

制作 Live 镜像时,压缩算法的选择直接影响体积和启动速度。常见的几个选项:

压缩算法压缩比解压速度适用场景
gzip中等老机器、追求启动速度
xz追求最小体积、机器性能较好
zstd很快现代 CPU,兼顾体积和速度

我在 mksquashfs 阶段手工重压时常用 zstd:

sudo mksquashfs /source/path rootfs.squashfs -comp zstd -Xcompression-level 19

zstd 级别越高压缩率越好,但打包时间也越长。我实测下来,level 19 和 level 15 的压缩比差距大概在 2%–3%,而压缩时间差了近一倍,所以日常用 level 15 就够了。

6. 制作和启动过程中最容易翻车的几个环节

最后这部分,我把这些年做 Live 镜像过程中踩过的坑整理出来。每一个我都给出了完整的排查思路,不是直接甩给你一个“改这里”的结论,而是希望你学会定位问题的方法。

6.1 启动后卡在 “waiting for device”,如何定位

这个错误是最常见的,也是最让人恼火的,因为屏幕上没有任何有效提示。

我的排查链路是:

  1. 先确认卷标。在引导菜单按 Tab 或 e 编辑启动参数,核对root=live:LABEL=xxx是否和 ISO 实际卷标完全一致,包括大小写。
  2. 在按 Enter 启动前,把quiet参数去掉,让内核输出详细信息。看到/dev/disk/by-label/xxx找不到时,基本就能确定是卷标问题。
  3. 如果卷标没问题,考虑是不是 U 盘识别慢。某些老机器的 USB 控制器初始化晚于内核挂载根文件系统的动作,可以在启动参数里加rootdelay=10,强制等待几秒再挂载。

经验之谈:90% 的“waiting for device”都是卷标大小写问题,剩下 10% 是 U 盘主控兼容性。先抓卷标,别急着怀疑硬件。

6.2 实机启动黑屏,虚拟机却一切正常

镜像在虚拟机里跑得好好的,一到真机就黑屏或者花屏。这个问题的根源通常是内核缺少对应硬件的固件或显存管理驱动。

排查思路按下面走:

  1. 确认/lib/firmware目录是否完整。如果你的系统之前正常运行在这台机器上,那打包前应该是完整的;但如果你是从别的机器打包的,就很可能缺少当前机器需要的固件。
  2. 检查 initramfs 中是否包含了对应硬件的内核模块。可以用lsinitramfs查看:
    lsinitramfs /boot/initramfs-*.img | grep -i amdgpu
  3. 如果模块缺失,需要在源系统中先加载对应驱动再重新打包,或者在 initramfs 配置里添加模块。

一个实用技巧是:打包前在源系统里执行

sudo update-initramfs -u

确保 initramfs 和当前内核模块状态一致,然后再跑打包脚本。

6.3 FAT32 的 4GB 限制与 U 盘格式选择

如果你把镜像写到 FAT32 格式的 U 盘,单个文件超过 4GB 就无法存储,而制作出来的 Live 镜像经常超过这个数。

解决方案有三个:

  • 把 ISO 写入 U 盘(用 dd 或写盘工具)——这种方式不做分区,直接把镜像写进整块盘,不存在 FAT32 限制。
  • 使用 U 盘分区方案,第一个分区保持 FAT32 用于存储文件,第二个分区是持久化分区。这时应确保 rootfs.squashfs 单独存储在可支持大文件的分区中,或者拆分 squashfs 文件。
  • 不用 FAT32,直接用 ext4 或 exFAT 格式 U 盘,配合引导加载器正确识别。

我自己后来基本都用 dd 整盘写入,虽然 U 盘上不能再随意存文件,但稳定性最好,兼容性也最高。

6.4 文件权限和符号链接被破坏

如果你在打包过程中用了不恰当的命令(比如直接复制而不是用 rsync),容易出现符号链接变成普通文本文件、可执行权限丢失、suid 位被清除等问题。这些往往不会在启动时立刻暴露,而是在运行某个程序时突然报“permission denied”或“cannot execute binary file”。

我踩过一次大坑:打包时用了cp -r同步系统根目录,结果/bin/busybox变成了普通文件,Live 系统起来后一堆命令不可用。从那以后我坚持两点:

  • 所有文件同步都必须用支持保留属性的工具,首推 rsync。
  • 打包完成后,对比原始系统的符号链接数量,验证完整性:
find / -type l | wc -l

如果在 Live 系统里也有同样命令,做个数量对比就能发现异常。

6.5 UEFI 安全启动与引导失败

新机器默认开启 Secure Boot,自制镜像一般没有有效的签名,会被拒之门外。有些人一上来就禁用 Secure Boot,在部分设备上是可以的,但有些企业管理和产线环境不允许。

我现在的处理方式是:先把 Secure Boot 在 BIOS 里临时关掉,验证镜像没问题后,再考虑是否需要加入签名。如果只是内部使用,关闭 Secure Boot 是一个并不违法违规的技术选择,纯属技术操作;如果需要正式发布,再研究 MOK 签名流程。实测下来,90% 的自制镜像并不涉及签名需求,内部工具盘没必要和自己过不去。


做了一遍完整的流程之后,我自己最大的体会就是:做 LiveCD 其实不是“把系统做成一个文件”这么简单,它背后是对 Linux 启动机制、文件系统、引导加载和硬件兼容性的全面理解。第一次成功做出能启动的镜像,那种成就感确实不错,但更实用的价值是,你从此拥有了一张能救命的“万能钥匙盘”。

最后再说一个长期使用的小建议:不要只在系统好的时候想起做 Live 镜像,定期在系统配置稳定后更新一份。我给自己定的节奏是每完成一个大版本升级、每部署完一套重要环境,就重新打一次包,顺手把镜像传到安全的存储位置。多花十几分钟,关键时刻可能为你省下一个通宵。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询