美美电子商务 發表於 2024-9-28 14:08:00

制作自定义的Debian-liveCD-ISO

<p>主要参考:https://willhaley.com/blog/custom-debian-live-environment/</p>
<h2 id="序章">序章</h2>
<p>先找到一块风水宝地作为我们的工作目录,所有相关文件都放到这个目录下。以下命令默认都是在这个目录下执行。</p>
<pre><code class="language-shell">mkdir -p 风水宝地
cd 风水宝地
</code></pre>
<p>P.S. <code>风水宝地</code>是个梗,建议尽量用英文目录名。</p>
<p>在风水宝地下面建立一些必要的目录:</p>
<pre><code class="language-shell">mkdir -p ./{staging/{EFI/boot,boot/grub/x86_64-efi,isolinux,live},tmp}
</code></pre>
<p>其中<code>staging</code>下面存放的就是用来制作ISO的文件。</p>
<p>然后安装必要的工具:</p>
<pre><code class="language-shell"># Debian 11
sudo apt install \
    debootstrap \
    squashfs-tools \
    xorriso \
    isolinux \
    syslinux-efi \
    grub-pc-bin \
    grub-efi-amd64-bin \
    mtools
</code></pre>
<h2 id="生成基本的linux根目录结构">生成基本的Linux根目录结构</h2>
<pre><code class="language-shell">sudo debootstrap bullseye $(pwd)/chroot https://mirrors.tuna.tsinghua.edu.cn/debian/
</code></pre>
<h2 id="安装linux内核">安装Linux内核</h2>
<pre><code class="language-shell">sudo chroot chroot/
</code></pre>
<p>然后在chroot里面:</p>
<pre><code class="language-shell"># chroot
apt install linux-image-amd64
</code></pre>
<p>注意这个时候生成的initramfs不是针对LiveOS的。安装<code>live-boot</code>之后会让系统中的<code>update-initramfs</code>指向<code>live-update-initramfs</code>,并且自动更新系统中已有的initramfs,使其可以用来启动LiveOS:</p>
<pre><code class="language-shell"># chroot
apt install live-boot
</code></pre>
<p>然后安装<code>systemd-sysv</code>(教程说是用来提供init的):</p>
<pre><code class="language-shell"># chroot
apt install systemd-sysv
</code></pre>
<p>最后退出chroot,将安装好的内核和initramfs拷贝到<code>staging</code>中:</p>
<pre><code class="language-shell">cp chroot/boot/vmlinuz-* \
    staging/live/vmlinuz &amp;&amp; \
sudo cp chroot/boot/initrd.img-* \
    staging/live/initrd
# 因为有些initramfs没有给others读权限。
sudo chown $USER:$USER staging/live/initrd
</code></pre>
<h2 id="更改根文件系统">更改根文件系统</h2>
<p>可以chroot进根文件系统更改:</p>
<pre><code class="language-shell">sudo chroot chroot/
</code></pre>
<p>可以更改<code>/etc/hostname</code>、添加用户、设置root密码等。也可以安装一些必要的包,修改一些配置:</p>
<pre><code class="language-shell"># chroot
apt install openssh-server
echo 'PermitRootLogin yes' &gt;&gt; /etc/ssh/sshd_config
</code></pre>
<p>用<code>apt</code>装完软件包之后,通常系统会把安装包缓存下来。可以通过<code>apt clean</code>把这些缓存清空。</p>
<p>这一阶段也可以配置自动登录到root:https://askubuntu.com/a/1229543<br>
(这个没有用:https://unix.stackexchange.com/questions/151919/login-automatically-as-root)</p>
<p>修改完根文件系统之后,就可以把它压缩为squashfs了:</p>
<pre><code class="language-shell">sudo mksquashfs \
    chroot \
    staging/live/filesystem.squashfs \
    -e boot
</code></pre>
<p>注意这里把<code>/boot</code>目录排除了,这是因为系统启动的时候会先读取<code>/boot</code>下面的内核等,最后才挂载根文件系统,因此<code>/boot</code>目录不能放到根文件系统里,而是另外放。</p>
<p>如果以后还要更改根文件系统,都要重新执行上面的命令生成<code>filesystem.squashfs</code>。</p>
<h2 id="boot-loader-menus">Boot Loader Menus</h2>
<pre><code class="language-shell">cat &lt;&lt;'EOF' &gt;staging/isolinux/isolinux.cfg
UI vesamenu.c32

MENU TITLE Boot Menu
DEFAULT linux
TIMEOUT 600
MENU RESOLUTION 640 480
MENU COLOR border       30;44   #40ffffff #a0000000 std
MENU COLOR title      1;36;44 #9033ccff #a0000000 std
MENU COLOR sel          7;37;40 #e0ffffff #20ffffff all
MENU COLOR unsel      37;44   #50ffffff #a0000000 std
MENU COLOR help         37;40   #c0ffffff #a0000000 std
MENU COLOR timeout_msg37;40   #80ffffff #00000000 std
MENU COLOR timeout      1;37;40 #c0ffffff #00000000 std
MENU COLOR msg07      37;40   #90ffffff #a0000000 std
MENU COLOR tabmsg       31;40   #30ffffff #00000000 std

LABEL linux
MENU LABEL Debian Live
MENU DEFAULT
KERNEL /live/vmlinuz
APPEND initrd=/live/initrd boot=live

LABEL linux
MENU LABEL Debian Live (nomodeset)
MENU DEFAULT
KERNEL /live/vmlinuz
APPEND initrd=/live/initrd boot=live nomodeset
EOF
</code></pre>
<pre><code class="language-shell">cat &lt;&lt;'EOF' &gt;staging/boot/grub/grub.cfg
search --set=root --file /DEBIAN_CUSTOM

set default="0"
set timeout=30

# If X has issues finding screens, experiment with/without nomodeset.

menuentry "Debian Live " {
    insmod all_video
    linux ($root)/live/vmlinuz boot=live
    initrd ($root)/live/initrd
}

menuentry "Debian Live (nomodeset)" {
    insmod all_video
    linux ($root)/live/vmlinuz boot=live nomodeset
    initrd ($root)/live/initrd
}
EOF
</code></pre>
<p>其中<code>insmod all_video</code>可以解决<code>no suitable video mode found</code>的问题:https://lists.gnu.org/archive/html/help-grub/2018-01/msg00009.html</p>
<pre><code class="language-shell">cat &lt;&lt;'EOF' &gt;tmp/grub-standalone.cfg
search --set=root --file /DEBIAN_CUSTOM
set prefix=($root)/boot/grub/
configfile /boot/grub/grub.cfg
EOF
</code></pre>
<pre><code class="language-shell">touch staging/DEBIAN_CUSTOM
</code></pre>
<p><code>DEBIAN_CUSTOM</code>的功能是帮助<code>GRUB</code>查找哪个设备包含了我们的live filesystem。因此其名字要全局唯一。</p>
<h2 id="boot-loader-files">Boot Loader Files</h2>
<p>这里直接把宿主机上的文件拷贝过来:</p>
<pre><code class="language-shell">cp /usr/lib/ISOLINUX/isohdpfx.bin tmp/
cp /usr/lib/ISOLINUX/isolinux.bin staging/isolinux/ &amp;&amp; \
cp /usr/lib/syslinux/modules/bios/* staging/isolinux/

mkdir -p staging/boot/grub/x86_64-efi/
cp -r /usr/lib/grub/x86_64-efi/* staging/boot/grub/x86_64-efi/
</code></pre>
<pre><code class="language-shell"># 如果是CentOS,就是grub2-mkstandalone
grub-mkstandalone \
    --format=x86_64-efi \
    --output=tmp/bootx64.efi \
    --locales="" \
    --fonts="" \
    "boot/grub/grub.cfg=tmp/grub-standalone.cfg"
</code></pre>
<pre><code class="language-shell">cd staging/EFI/boot
dd if=/dev/zero of=efiboot.img bs=1M count=20
/sbin/mkfs.vfat efiboot.img
mmd -i efiboot.img efi efi/boot
mcopy -vi efiboot.img ../../../tmp/bootx64.efi ::efi/boot/
cd -
</code></pre>
<h2 id="生成iso">生成ISO</h2>
<pre><code class="language-shell">xorriso \
    -as mkisofs \
    -iso-level 3 \
    -o "debian-custom.iso" \
    -full-iso9660-filenames \
    -volid "DEBIAN_CUSTOM" \
    -isohybrid-mbr tmp/isohdpfx.bin \
    -eltorito-boot \
      isolinux/isolinux.bin \
      -no-emul-boot \
      -boot-load-size 4 \
      -boot-info-table \
      --eltorito-catalog isolinux/isolinux.cat \
    -eltorito-alt-boot \
      -e /EFI/boot/efiboot.img \
      -no-emul-boot \
      -isohybrid-gpt-basdat \
    -append_partition 2 0xef staging/EFI/boot/efiboot.img \
    "staging"
</code></pre>
<h2 id="用qemu测试">用QEMU测试</h2>
<pre><code class="language-shell">qemu-system-x86_64 -enable-kvm -cpu host -m 4096 -cdrom debian-custom.iso
</code></pre>
<p>联网、VNC等参考:在服务器上用qemu制作虚拟机</p>
<h2 id="注意事项">注意事项</h2>
<p>这个ISO不支持ventoy。</p>
<h2 id="常见问题">常见问题</h2>
<h3 id="no-working-init">no working init</h3>
<p>可能是内存不足。因为liveCD好像是把整个根文件系统放到内存里,所以给的内存要足够大?</p>
<p>参考:https://unix.stackexchange.com/questions/655508/boot-ubuntu-iso-under-qemu</p>
<h3 id="no-loop-devices-available">No loop devices available</h3>
<p>检查内核的配置文件里<code>CONFIG_BLK_DEV_LOOP_MIN_COUNT</code>的值。如果是0的话,即使<code>modprobe loop</code>了,<code>ls /dev/loop0</code>仍然不存在。</p>
<p>Debian生成的initramfs好像要求这个值不能是0。Torvalds内核的默认配置里这个值是8,但是CentOS的内核配置里这个值是0。因此如果发现这个值是0(比如这个内核来自CentOS),那只能把这个值改成非0然后重新编译了。编译安装Linux内核教程:编译安装linux内核</p>
<h3 id="fb0-switching-to-amdgpudrmfb-from-efi-vga">fb0: switching to amdgpudrmfb from EFI VGA</h3>
<p>使用nomodeset模式即可。intel的机器没有这个问题。</p>
<p>参考:https://forum.level1techs.com/t/fb0-switching-to-amdgpudrmfb-from-efi-vga/152112</p>
<p><code>nomodeset</code>的作用:https://askubuntu.com/questions/207175/what-does-nomodeset-do</p>
<h3 id="chroot下dns解析失败">chroot下DNS解析失败</h3>
<p>chroot下貌似是不会自动更新<code>/etc/resolv.conf</code>的。因此把chroot目录转移到其他机器上再chroot就会出问题。可以把<code>/etc/resolv.conf</code>里改成<code>nameserver 8.8.8.8</code>之类的。</p>
<p>LiveOS好像不存在这个问题,因为开机的时候会自动更改<code>/etc/resolv.conf</code>。</p><br><br>
来源:https://www.cnblogs.com/searchstar/p/18437677
頁: [1]
查看完整版本: 制作自定义的Debian-liveCD-ISO