详解:把 Linux 系统做成 Livecd
详解:把 Linux 系统做成 Livecd
本文比较长,制作 LiveCD 的时间也比较长
Linux Livecd 有很多好处,比如常用于修复受损的系统,可以随时随地用一台电脑启动,对于 kali linux 来说用来做好人好事不留名,很刑很好。但是目前网上相关制作资料大多很差:
- 要么是非常古老的资料,甚至十年前还是32位的制作方法。
- 要么一通乱写,各种命令的作用、后果完全不讲,工作目录也不管,他自己做完了而我们很难跟得上。
- 要么很多方法早已弃用。
- 即使是很多官方文档也多年没有更新。
我会尽可能比较详细认真地讲解一下制作方法。
Kali Linux 发行版自带 Livecd:kali-linux-2023.4-live-amd64.iso,但对于我来说,不符合我的要求。我希望的 Kali Livecd 是:
- 有图形界面,预装微信、QQ、vscode、搜狗输入法等软件以便于使用。
- 自带 ssh 密钥等以方便随时随地连接服务器。
- 修改外观以使得其符合个人审美。
我摸爬滚打很长时间之后终于差不多搞明白制作方法了,我也成功制作了一个满足上述要求的 LiveCD,大概 1.6 GB(如果带上那些 kali linux 自带的网络安全方面的工具则有 4.0GB;原始 Kali Livecd 大概 4.3G),能方便地修复系统、随时工作还是很香的。我的 Livecd:https://www.cnblogs.com/KZ25T/p/18269916
最终效果:
准备材料
- 电脑(x86_64,UEFI启动)别的情况的我不好说。
- 电脑里有一个预装的 Linux A,有 sudo 和一定的空闲空间,建议 50GB
- 最好是 Debian 系发行版,不是 Debian 系应该也不是大问题
- docker 也行,wsl 应该也可以。
- 另有预留空间以安装 Linux B,目标是把 B 制作成 LiveCD;
- 如果只需要制作一个简单 Livecd 而不需要“把 B 制作成 Livecd”,那么就不需要 Linux B 了。
- B 是要一个完整的操作系统,docker、wsl 不行。
- 如果空间不足,可以使用外置硬盘。
- B 不要求是 Debian 系。
- 大容量(≥8GB)高速(≥usb3.0)外置存储设备,最好是移动硬盘,U盘也可以。不然做实验中,如果多次拷贝可能会比较慢。我从电脑城手里收的25块120G、50块240G SATA固态,搭配某摇一摇软件买的十块钱的 usb3.0 硬盘盒暂未翻车(翻车了也不心疼)
操作步骤
1. 安装 Linux B
我这里A 和 B 都是 Kali Linux;安装的详细过程不再细说,可以参考我其他的文章:
需要注意的事情有:
- 只安装必要、常用的软件。
- 图形界面安装轻量的 xfce 可以节省空间。
- 不要安装太多,这会导致最终的 iso 过大。比如我安装 QQ、vscode、搜狗输入法以及一些上网软件,这些比较常用。
- 至于 WPS 等软件,感觉并不会很常用,需要用的时候上网下载安装即可。
- 修改配置文件。
- 比如把 ssh 密钥拷贝过去:
cp LinuxA/home/xxx/.ssh LinuxB/home/xxx -r
可以方便 ssh 上服务器。 - gpg、git、vim 等同理。
- VSCode 同步插件,并只选择常用的,删除不常用的。删除缓存。
- 比如把 ssh 密钥拷贝过去:
- 删除缓存。如 QQ 各种缓存、VSCode 加载的缓存,还有 bash 或 zsh_history 等。
- 调整桌面环境到一个自己喜欢的状态。
- 删除多余软件及备用内核。另外一般发行版还有初始 initramfs,备用的也要删除。
- 更新、删除多余软件:
sudo apt update + upgrade + autoremove
- 删除 apt 缓存:
sudo apt clean
- 生成新的 initramfs:很多发行版都需要 initramfs 启动。看一下
ls /boot
及ls /lib/modules
里,最晚的一组 vmlinuz、initrd.img 和 module 的名字,比如initrd.img-6.5.0-kali3-amd64
,重新生成它:sudo mkinitramfs -k -o /boot/initrd.img-xxxxx xxxxx
,并保证其能启动。 - 成功重启之后删除其他的 vmlinuz/initramfs/modules:
sudo apt remove --purge linux-image-xxx
以及sudo rm -rf /lib/modules/xxx
,xxx 是所有不是最新的内核套件的后缀。
- 更新、删除多余软件:
另外,制作 livecd 的系统貌似还需要安装 livecd 专用工具,包括 live-tools
和 live-boot
(apt直接安装)
我感觉……大概装完这些就好了。
总之,B 应该是在干净和实用中取一个平衡的位置。我这里强调了干净这一点。此时我的系统大约 18GB;
2. 复制操作系统 B
在 A 中找个位置把 B 的所有文件拷贝进来:
sudo mount B分区 B挂载位置 # 挂载
sudo mkdir /LinuxB # 找个位置
sudo cp -rp B挂载位置 /LinuxB # 保存全部权限
进一步清一下缓存,或者一些不需要的东西。不会清就算了,不是大问题。
3. 利用 Debian Live-build 制作简单的 Debian Livecd
sudo apt install live-build
Debian 官方制作工具,不过看起来好些年了,也确实可能有点问题。
其他发行版:该软件包依赖于 debootstrap,除此之外看样子没有太多奇怪的依赖,可以在别的地方 apt download 搞来包之后手动解包安装,或者开个 docker 也行。
sudo mkdir /live # 随便找个位置
cd /live
sudo lb clean # 不知道为什么用这个名,这一步生成了 .build
sudo lb build # 先别急着做
按照官方文档,最后一步执行完之后就能在 /live
下生成一个 livecd iso了,但看样子它可能有不少问题。而且 lb 的脚本过于复杂,看不懂,于是就一路到处尝试。这里我遇到几个问题,几乎全是 apt:
-
首先是 apt 源。其直接使用默认 apt 源下载,也没找到什么配置的地方。所以速度特别慢。以下是一种解决办法:
sudo lb build
之后大概一两秒之后就会显示一行文字:I: Retrieving InRelease
然后就开始慢了。按 ctrl+c 中断。经过我的十几次尝试,发现
config/bootstrap
出现了一堆疑似软件源的链接,改了就能好一些,比如选择科大源:sudo sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' ./config/bootstrap
回去重新 build 有些地方就快了。
如果你去看了一下这个文件的内容,可能会发现里边还有 Debian security 的链接,我也尝试换源了,但是换完之后就一堆 verify error,不换就特别慢,暂时没找到啥好的办法。
-
第二个还是 apt 源,此 apt 源非彼 apt 源。等到
./chroot
初步形成基本目录的时候(忘了啥时候了),你可能会发现其/etc/apt/sources.list
里还是 deb.debian.org,这个文件还得换,sudo sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' ./chroot/etc/apt/sources.list
换完之后重新 build;
-
第三个还是 apt 源,因为 Debian 过于追求干净所以有的包在 main 仓库里不存在,忘了什么时候了,大概是第一次出问题停下来的时候(个人感觉越早越好,上一步可以接着这个),把 non-free 加到软件源的每一行里:
sudo sed -i 's/$/ non-free/g' ./chroot/etc/apt/sources.list
记得看看文件内容,检查一下是不是改错了。
chroot 进去,apt update,回来重新 build
-
第四个还是 apt,有几次停下来是因为找不到包(即使上边加上 non-free 了),这时候手动 chroot 去装。感觉应该是这个工具太老了所以有的包名字有变化,自己 apt search 一下找找正确的包名。
大概经历这些千辛万苦之后就会在工作目录下出现一个 live-image-amd64.hybrid.iso
,你就可以拿它去刻录到硬盘/U盘上启动了:
sudo dd if=live-image-amd64.hybrid.iso of=/dev/sda # 移动硬盘位置,lsblk查看,别搞错了
这里分享一下我做出来的:百度网盘 大概 175MB,你的制作过程可能比从这里下载还慢。
这个 livecd 没法挂载 ext4,没法连 WiFi,甚至找不到无线网卡。甚至它还没有 dhcp,有线网也几乎上不了。所以这个只能证明理论上可以启动,实用性几乎没有。
4. 对于构建 iso 的探索
这一步很多内容不影响你最终的 livecd 生成,但我建议你看
我们需要知道这个 iso 是咋生成的。
首先,在 /live 下大概有这些东西:
$ ls -A .
auto chroot live-image-amd64.contents live.zip
binary chroot.files live-image-amd64.files local
binary.modified_timestamps chroot.packages.install live-image-amd64.hybrid.iso
.build chroot.packages.live live-image-amd64.hybrid.iso.zsync
cache config live-image-amd64.packages
其中是目录的是:
auto binary .build cache chroot config local
首先 chroot 正如其名就是像个操作系统根目录。
然后我们试试打开 iso 看看内容,比对一下这里的内容,会发现它和 binary
里的东西十分甚至九分的相似:
$ ls -A binary
boot .dist EFI efi.img isolinux live sha256sum.README sha256sum
在 .disk 里我们就会发现这样一个东西:
$ ls binary/.disk/
archive_trace info mkisofs
前两个貌似没什么用,最后一个打开看像是一个生成 iso 的命令:
$ cat binary/.disk/mkisofs
xorriso -as mkisofs -R -r -J -joliet-long -l -cache-inodes -iso-level 3 -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin -partition_offset 16 -A "Debian Live" -p "live-build 20230502+kali2; https://salsa.debian.org/live-team/live-build" -publisher "Debian Live project; https://wiki.debian.org/DebianLive; debian-live@lists.debian.org" -V "Debian bullseye 20231212-21:32" --modification-date=2023121213324700 -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot --efi-boot boot/grub/efi.img -append_partition 2 0x01 binary/boot/grub/efi.img -o live-image-amd64.hybrid.iso binary
试了一下,执行这个命令确实能打包生成 iso,而且各种引号里的东西都能随便改,modification-date 也能随便改,于是我用这个命令生成:
sudo xorriso -as mkisofs -R -r -J -joliet-long -l -cache-inodes -iso-level 3 -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin -partition_offset 16 -A "myLive" -p "myBuild" -publisher "myName" -V "myLiveVolume" --modification-date=2023121300000000 -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot --efi-boot boot/grub/efi.img -append_partition 2 0x01 binary/boot/grub/efi.img -o my.iso binary
确实能生成 my.iso
,dd刻录之后成功启动。很多参数咱也看不懂(之前我用过好多次 xorriso 都经常出各种问题,这个倒是没啥问题),先不管那么多,接下来就用这个命令生成 iso 即可。
刚发现 CSDN 上了一个自动注释功能,这是它写的注释,我没去查证真实性,也先不用管:
sudo xorriso -as mkisofs \
-R -r -J -joliet-long -l -cache-inodes -iso-level 3 \ # 设置ISO文件系统的选项
-isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin \ # 设置ISO的引导方式为isohybrid
-partition_offset 16 \ # 设置分区偏移量
-A "myLive" \ # 设置卷标
-p "myBuild" \ # 设置预发行者
-publisher "myName" \ # 设置发布者
-V "myLiveVolume" \ # 设置卷名
--modification-date=2023121300000000 \ # 设置修改日期
-b isolinux/isolinux.bin \ # 设置ISO引导文件
-c isolinux/boot.cat \ # 设置启动目录
-no-emul-boot \ # 设置光盘启动模式
-boot-load-size 4 \ # 设置引导加载大小
-boot-info-table \ # 启用引导信息表
-eltorito-alt-boot --efi-boot boot/grub/efi.img \ # 设置EFI引导文件
-append_partition 2 0x01 binary/boot/grub/efi.img \ # 添加一个符合GPT标准的引导分区
-o my.iso binary # 输出的ISO文件名
最后一条肯定不对,binary 是源文件的目录名。
我们再来看看 binary 有什么(省略了部分文件):
$ tree binary -a
binary/
├── boot
│ └── grub
│ ├── config.cfg
│ ├── efi.img
│ ├── grub.cfg
│ ├── i386-efi
│ │ ├── acpi.mod
│ │ │ (省略)
│ │ └── zstd.mod
│ ├── live-theme
│ │ └── theme.txt
│ ├── loopback.cfg
│ ├── theme.cfg
│ ├── unicode.pf2
│ └── x86_64-efi
│ ├── acpi.mod
│ │ (省略)
│ └── zstd.mod
├── .disk
│ ├── archive_trace
│ ├── info
│ └── mkisofs
├── EFI
│ └── boot
│ ├── bootia32.efi
│ ├── bootx64.efi
│ └── grubx64.efi
├── efi.img
├── isolinux
│ ├── hdt.c32
│ │ (省略了一些 c32)
│ ├── isolinux.bin
│ ├── isolinux.cfg
│ ├── live.cfg
│ ├── menu.cfg
│ ├── splash800x600.png
│ ├── splash.png
│ ├── stdmenu.cfg
│ ├── utilities.cfg
│ └── vesamenu.c32
└── live(好像还有点别的东西,但我删了)
├── filesystem.squashfs
├── initrd.img
├── initrd.img-xxx
├── vmlinuz
└── vmlinuz-xxx
10 directories, 546 files
像这些 EFI 文件,咱也不知道都有啥用,不敢动。其他的就是像 grub 里常见的配置文件,会改 grub 的可以自己改一下配置,换个自己喜欢的主题。像我改成了纯色:
$ sudo vim binary/boot/grub/live-theme/theme.txt
文字颜色什么的
top 什么的也可以自己改
还有这里边的 desktop-image 貌似并不能去掉,去了之后启动报错(不过也能启动),于是生成透明的 png 图片,替代 isolinux 下面的两张图:
# chatgpt 告诉我的
ffmpeg -f lavfi -i color=c=black@0:size=800x600,format=rgba -frames:v 1 binary/isolinux/splash800x600.png
ffmpeg -f lavfi -i color=c=black@0:size=640x480,format=rgba -frames:v 1 binary/isolinux/splash.png
换成透明图之后,grub 启动页面背景变黑了,这不重要,看起来十分具有 unix 遗风。
于是我又换了个表情包当背景:
结果全屏了:
试了一下, ffmpeg 可以调整亮度,调完了正常一些:
ffmpeg -i in1.png -vf "eq=brightness=-0.5" out1.png
把两张图都调完之后正常一点:
此处设置的未选中颜色是 #ffffff,选中颜色是 #66ccff
又试了一下,看样子似乎并不要求图像尺寸。
grub 的修改就到此为止。
然后我们发现 live 里的 initrd.img 和 vmlinuz 分别有两个,diff 一下还都一样,于是猜测分别删一个,只留下短的。里边的 filesystem.squashfs 开头的文件,除了那个最大的(就是不带任何后缀)别的可以试一下都删了也没问题。于是 live 下面就留了三个文件:
$ ls binary/live
filesystem.squashfs initrd.img vmlinuz
记得把 grub 选项也给改了:
$ sudo vim binary/boot/grub/grub.cfg
# 把每一项的 linux 和 initrd 那两行的文件都给改了,就是把 initrd.img-xxx 和 vmlinuz-xxx 后缀去掉
除此之外,各种什么 md5 之类的都可以删,.disk 里的 archive_trace 和 mkisofs 也可以删,info 删了就爆炸,不过好像内容可以随便写,不知道为什么。最后用上边那个超长 xorriso
命令打包,试一下能不能启动,看来是可以的。
以上都是我启动了几十遍 livecd 试出来的结果
于是我们可以总结出最简 binary 目录结构:
binary/
├── boot
│ └── grub
│ ├── config.cfg
│ ├── efi.img
│ ├── grub.cfg(一定要改)
│ ├── i386-efi(省略)
│ ├── live-theme
│ │ └── theme.txt(可以自己改)
│ ├── loopback.cfg
│ ├── theme.cfg
│ ├── unicode.pf2
│ └── x86_64-efi(省略)
├── .disk
│ └── info(必须有,但内容疑似随便写)
├── EFI
│ └── boot
│ ├── bootia32.efi
│ ├── bootx64.efi
│ └── grubx64.efi
├── efi.img
├── isolinux
│ ├── (省略了一些 c32,不知道干啥的)
│ ├── isolinux.bin
│ ├── isolinux.cfg
│ ├── live.cfg
│ ├── menu.cfg
│ ├── splash800x600.png(可以改)
│ ├── splash.png(可以改)
│ ├── stdmenu.cfg
│ └── utilities.cfg
└── live
├── filesystem.squashfs(文件系统)
├── initrd.img (大部分发行版都有的启动 ramfs)
└── vmlinuz (内核)
5. 对于构建 squashfs 的探索
毋庸置疑,这里的 squashfs 是用 chroot 内的内容构造的。那么是如何构造的?
虽然我没找到构造命令,但是注意到:
$ file binary/live/filesystem.squashfs
binary/live/filesystem.squashfs: Squashfs filesystem, little endian, version 4.0, xz compressed, xxxxx bytes, xxxxx inodes, blocksize: 131072 bytes, created: Wed Dec 13 08:52:29 2023
可以看到是 xz 压缩。Unsquashfs 挂载看一下, diff -recursive 对比一下 chroot,几乎相同,不同的主要是把内核及 initramfs 删了。于是尝试使用这个命令:
sudo rm binary/live/filesystem.squashfs # 好像必须要先删除,否则出问题
cd chroot
sudo mksquashfs . ../binary/live/filesystem.squashfs -comp xz -e ./vmlinuz -e ./vmlinuz.old -e ./initrd.img -e ./initrd.img.old -e ./boot/* -e ./etc/fstab -e ./etc/NetworkManager/system-connections/*
cd -
最后两项是:一个是需要排除挂载文件系统(livecd不需要按照常规系统挂载),第二个是删除网络连接配置。可以视情况自行调整。
打包刻录启动,正常启动。
为了能上网,我们试试 chroot 进去安装:
$ sudo chroot live
(live) $ apt install net-tools wireless-tools iw iwd wpasupplicant # 大概是这几样东西
(live) $ # 按 ctrl+D 退出
制作 squashfs,打包刻录启动,正常启动后可以上网。
6. 把系统 B 制作成 livecd
先看一下我的最终结果:
$ file my.iso
my.iso: ISO 9660 CD-ROM filesystem data (DOS/MBR boot sector) 'KaliLive' (bootable)
$ ll my.iso
-rw-r--r-- 1 root root 5.1G 12月14日 08:55 my.iso
$ md5sum my.iso
56b8416bd11d6fc4845d2d054302ec01 my.iso
至此,看样子 livecd 只差仿照 5 这一步,只差 live 里的三个文件了。我们把 B 进行类似的操作:
$ cd /LinuxB
$ sudo mksquashfs . /live/binary/live/filesystem.squashfs -comp xz -e ./vmlinuz -e ./vmlinuz.old -e ./initrd.img -e ./initrd.img.old -e ./boot/* -e ./etc/fstab -e ./etc/NetworkManager/system-connections/*
$ sudo cp boot/vmlinuz-xxx /live/binary/live/vmlinuz
$ sudo cp boot/initrd.img-xxx /live/binary/live/vmlinuz
接下来需要注意的就是 grub 引导参数。以我的 kali 为例,正常的系统的启动引导参数:
$ vim -R /boot/grub/grub.cfg
# 观察正常启动的选项中,linux 开头的那一行。我的是:
# linux /boot/vmlinuz-xxx root=UUID=xxx ro quiet split_lock_detect=off splash
kali 有 livecd,可以从网上下载 kali livecd 看一下引导参数:
# 打开 kali 原装 livecd 的 iso,看 boot/grub/grub.cfg
# menuentry "Live system (amd64)" --hotkey=l {
# linux /live/vmlinuz-xxx boot=live components quiet splash noeject findiso=${iso_path}
# initrd /live/initrd.img-xxx
# }
再看一下我们制作的 Debian Livecd 的引导参数:
$ cat binary/boot/grub/grub.cfg
# menuentry "Live system (amd64)" --hotkey=l {
# linux /live/vmlinuz boot=live components quiet splash findiso=${iso_path}
# initrd /live/initrd.img
# }
综合对比一下,自己选一个合适的参数,修改 binary/boot/grub/grub.cfg
相应位置。我这里直接选择了 kali livecd 的选项,也就是 debian 的引导参数加上 noeject 一项,其实我并不只是每一项都是啥意思,但这样其实也确实能启动。
另外,fall-safe mode 的参数也可以同样适当修改。
打包刻录启动测试,一气呵成,成功。
7. 听说有的人完全没学会,卡在第3步?
那我给一个最简单的方法:
对于 binary
目录,如果都是 x86_64 电脑,那么我们做出来应该都一样。我直接把我做的 binary 献上来:百度网盘,只有 8MB(删了 binary/live 里需要自己填的 3 个文件,下载很快),不过这里已经是我(针对自己的需求)调整过 grub 外观和引导参数,并删除我能找出来的多余文件的。
现在你需要做的是:
- 解压文件:
sudo mkdir /live sudo unzip live.zip -d /live sudo mv /live/live/binary /live sudo rmdir /live/live # 现在 /live 下,应该只有一个 binary
- 按照第 1、2 步构造 B
- 复制 B 的相关文件到
live
里:cd /LinuxB sudo mksquashfs . /live/binary/live/filesystem.squashfs -comp xz -e ./vmlinuz -e ./vmlinuz.old -e ./initrd.img -e ./initrd.img.old -e ./boot/* -e ./etc/fstab -e ./etc/NetworkManager/system-connections/* sudo cp boot/vmlinuz-xxx /live/binary/live/vmlinuz sudo cp boot/initrd.img-xxx /live/binary/live/initrd.img
- 根据你的实际情况,调整
/live/binary/boot/grub/grub.cfg
的引导参数和 grub 外观、 - 打包:
cd /live/binary sudo xorriso -as mkisofs -R -r -J -joliet-long -l -cache-inodes -iso-level 3 -isohybrid-mbr /usr/lib/ISOLINUX/isohdpfx.bin -partition_offset 16 -A "myLive" -p "myBuild" -publisher "myName" -V "myLiveVolume" --modification-date=2023121300000000 -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -eltorito-alt-boot --efi-boot boot/grub/efi.img -append_partition 2 0x01 binary/boot/grub/efi.img -o my.iso binary
- 刻录,启动:
重启后选择外置 USB 设备启动,方法根据电脑品牌自己查。sudo dd if=/live/my.iso of=/dev/sda # of 是外置 USB 移动硬盘或 U 盘的设备名