ehi*_*ler 15 boot debian bootable debootstrap
过去 2 天,我一直在尝试创建可引导的 debian (jessie/8.4) 映像,据我所知,我的程序正确,但我无法正确设置文件系统。我相对确定我在这里做错了什么,缺少安装或/etc/fstab(我的图像中没有)。我希望有一些经验的人能够帮助我/向我展示我所缺少的东西。
以下是我在启动 qemu-system-x86 时看到的错误:
作为文本,然后作为实际屏幕截图:
fsck: error 2 (No such file or directory) while executing fsck.ext2 for /dev/sda1
fsck exited with status code 8
[FAILED] Failed to start Load/Save Random Seed
See `systemctl status systemd-random-seed.service` for details.
[FAILED] Failed to start Various fixups to make systemd work better on Debian.
See `systemctl status debian-fixup.service` for details.
...
[FAILED] Failed to start Update UTMP about System Boot/Shutdown.
See `systemctl status systemd-update-utmp.service` for details.
[DEPEND] Dependency failed for Update UTMP about System Runlevel Changes.
Run Code Online (Sandbox Code Playgroud)
以下是我为自己编写的说明/我已采取的步骤:
cd ~
mkdir debootstrap
cd debootstrap/
# get newest
wget http://ftp.debian.org/debian/pool/main/d/debootstrap/debootstrap_1.0.80_all.deb
ar -x debootstrap_1.0.80_all.deb
zcat /root/debootstrap/data.tar.gz | tar xv
apt-get install parted
# 1.5Gbytes
dd if=/dev/zero of=1445.img bs=1024 count=1 seek=1536k
parted -s 1445.img -- mklabel msdos mkpart primary 1m 1.5g toggle 1 boot
losetup --show -f 1445.img
# prints out `/dev/loopX`, enter this on the next lin
partprobe /dev/loop0
# only have to make the filesytem once --> if you are troubleshooting steps, do not redo this line
mkfs -t ext2 /dev/loop0p1
mount /dev/loop0p1 /mnt
debootstrap --verbose --components=main,contrib,non-free \
--include=firmware-realtek,linux-image-amd64,grub-pc,ssh,vim \
--exclude=nano \
--arch amd64 jessie /mnt http://ftp.us.debian.org/debian
Run Code Online (Sandbox Code Playgroud)
确保内核已安装,它应该出现在 /boot chroot 中,即 /mnt/boot 包含以下文件:
initrd.img-3.16.0-4-amd64vmlinuz-3.16.0-4-amd64config-3.16.0-4-amd64System.map-3.16.0-4-amd64安装 grub
grub-install --boot-directory=/mnt/boot --modules=part_msdos /dev/loop0
Run Code Online (Sandbox Code Playgroud)设置 APT
复制 apt 源
cp /etc/apt/sources.list /mnt/etc/apt/sources.list
Run Code Online (Sandbox Code Playgroud)确保cdrom源被注释掉
添加行:
deb http://ftp.debian.org/debian stable-backports main contrib non-free
Run Code Online (Sandbox Code Playgroud)mount --bind /dev/pts /mnt/dev/pts
mount --bind /proc /mnt/proc
mount --bind /sys /mnt/sys
mount --bind /dev /mnt/dev
# if you want your pushprofilesettings
cp ~/.bashrc /mnt/root/
cp ~/.vimrc /mnt/root/
# chroot -- enter the system as if it were thy own
chroot /mnt /bin/bash
export HOME=/root
export LC_ALL=C
export LANG=C.UTF-8
export TERM=xterm-256color
Run Code Online (Sandbox Code Playgroud)
mount from man mount:
--bind 在其他地方重新安装子树(其内容在两个地方都可用)。
-t <type>文件系统类型的挂载,有了这个,mount将尝试自动确定
编辑/etc/default/grub:
设置GRUB_CMDLINE_LINUX=""为:
GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,115200n8"
Run Code Online (Sandbox Code Playgroud)取消注释 GRUB_TERMINAL=console
在下面添加一行:
GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"
Run Code Online (Sandbox Code Playgroud)进行 grub 配置 -这 必须 在非systemd-nspawnshell 中完成(这意味着 chroot)
grub-mkconfig -o /boot/grub/grub.cfg
Run Code Online (Sandbox Code Playgroud)
exit
Run Code Online (Sandbox Code Playgroud)
umount /mnt/sys
umount /mnt/dev
umount /mnt/dev/pts
umount /mnt/proc
Run Code Online (Sandbox Code Playgroud)
可以使用以下命令检查其他安装: mount | grep /mnt 然后卸载它们 umount
systemd-nspawn -D /mnt
# not you are in a special container
Run Code Online (Sandbox Code Playgroud)
设置密码root与passwd
在/etc/ssh/sshd_config注释PermitRootLogin without-password中阅读#PermitRootLogin without-password并插入PermitRootLogin yes它下面
现在在启动时启用 ssh
systemctl enable ssh
Run Code Online (Sandbox Code Playgroud)
# this is needed to clean up both chroot and systemd-nspawn -D /mnt
# once this is run you can not do systemd-nspawn either so wait until you are entirely done
exit
umount /mnt
losetup -d /dev/loop0
Run Code Online (Sandbox Code Playgroud)
使用以下命令检查其他安装: mount | grep /mnt 如果 返回任何 内容,请使用以下命令卸载它们 umount
如果您弄坏了某些东西,或者需要重试,请在现有的上重新安装/设置 CHROOT .img:
losetup --show -f 1445.img
# prints out `/dev/loopX`, enter this on the next lin
partprobe /dev/loop0
mount /dev/loop0p1 /mnt
Run Code Online (Sandbox Code Playgroud)
qemu-system-x86_64 -hda 1445.img -m 1024 -vnc :0
Run Code Online (Sandbox Code Playgroud)
坚持并弄清楚,从这里开始相对简单,但不仅仅是设置问题,/etc/fstab其余的是:
没有必要,但清理东西的好主意
apt-get autoclean
Run Code Online (Sandbox Code Playgroud)
设置/etc/fstab- 检查mount以确保您使用正确的文件系统类型
echo "/dev/sda1 / ext4 defaults,errors=remount-ro 0 1" > /etc/fstab
Run Code Online (Sandbox Code Playgroud)
这将重建 initramfs 并允许它启动干净
update-initramfs -u -k all
Run Code Online (Sandbox Code Playgroud)
这样做,机器启动干净,在 QEMU 中测试,然后我现在在硬件上运行它。
自动 Debian 9 设置,没有任何 systemd 错误
这个设置没有任何 systemd 错误或警告,最后我得到了 Internet 连接和一个 shell。
这个设置并不完美,因为我没有使用 Debian 内核,我在后面的部分中解释了我尝试时的错误。然后我只是尝试了一个我躺在身边的内核,它的配置基于 Buildroot并且它有效。此设置中提供了配置。因此,某些依赖于缺少内核配置的软件包可能会失败,尽管到目前为止我还没有观察到任何错误。
但是,类似的设置与 Ubuntu 内核完美配合:https ://askubuntu.com/questions/281763/is-there-any-prebuilt-qemu-ubuntu-image32bit-online/1081171#1081171 Ubuntu 内核必须缺少配置与 Debian 相比。Debian 内核故障可能可以通过使用额外选项编译 Debian 内核来修复,就像CONFIG_VIRTIO_BLK=y我为 Ubuntu 所做的那样。
#!/usr/bin/env bash
set -eux
debootstrap_dir=debootstrap
root_filesystem=img.ext2.qcow2
sudo apt-get install \
debootstrap \
libguestfs-tools \
git \
qemu-system-x86 \
;
if [ ! -d "$debootstrap_dir" ]; then
# Create debootstrap directory.
# - linux-image-amd64: downloads the kernel image
sudo debootstrap \
--include linux-image-amd64 \
stretch \
"$debootstrap_dir" \
http://deb.debian.org/debian/ \
;
sudo rm -f "$root_filesystem"
fi
if [ ! -f "$root_filesystem" ]; then
# Set root password.
echo 'root:root' | sudo chroot "$debootstrap_dir" chpasswd
# Remount root filesystem as rw.
# Otherwise, systemd shows:
# [FAILED] Failed to start Create Volatile Files and Directories.
# and then this leads to further failures in the network setup.
cat << EOF | sudo tee "${debootstrap_dir}/etc/fstab"
/dev/sda / ext4 errors=remount-ro,acl 0 1
EOF
# Network.
# We use enp0s3 because the kernel boot prints:
# 8139cp 0000:00:03.0 enp0s3: renamed from eth0
# This can also be observed with:
# ip link show
# Without this, systemd shows many network errors, the first of which is:
# [FAILED] Failed to start Network Time Synchronization.
cat << EOF | sudo tee "${debootstrap_dir}/etc/network/interfaces.d/00mytest"
auto lo
iface lo inet loopback
auto enp0s3
iface enp0s3 inet dhcp
EOF
# Generate image file from debootstrap directory.
# Leave 1Gb extra empty space in the image.
sudo virt-make-fs \
--format qcow2 \
--size +1G \
--type ext2 \
"$debootstrap_dir" \
"$root_filesystem" \
;
sudo chmod 666 "$root_filesystem"
fi
# linux_image="$(printf "${debootstrap_dir}/boot/vmlinuz-"*)"
linux_img=linux/arch/x86_64/boot/bzImage
if [ ! -f "$linux_img" ]; then
# Build the Linux kernel.
git clone --depth 1 --branch v4.18 git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
cd linux
wget https://gist.githubusercontent.com/cirosantilli/6e2f4975c1929162a86be09f839874ca/raw/6d151d231a233408a6e1b541bf4a92fd55bf5338/.config
make olddefconfig
make -j`nproc`
cd -
fi
qemu-system-x86_64 \
-append 'console=ttyS0 root=/dev/sda' \
-drive "file=${root_filesystem},format=qcow2" \
-enable-kvm \
-serial mon:stdio \
-m 2G \
-kernel "$linux_img" \
-device rtl8139,netdev=net0 \
-netdev user,id=net0 \
;
Run Code Online (Sandbox Code Playgroud)
现在从终端,使用root/登录root,然后使用以下命令检查 Internet 是否正常工作:
printf 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n' | nc example.com 80
apt-get update
apt-get install hello
hello
Run Code Online (Sandbox Code Playgroud)
我们nc按照/sf/ask/2263906291/#52662497 中的解释使用,因为:
wget并且curl默认情况下未安装ping默认情况下在 QEMU 中不起作用:如何从 QEMU 来宾 ping 到外部 URL?在 Ubuntu 18.04 主机上测试。
如果我尝试使用 Debian 内核会发生什么
TODO 理解并修复。如果我用 Debian 打包的 Linux 内核替换上面的 Linux 内核编译:
linux_img="${debootstrap_dir}/boot/vmlinuz-"*
Run Code Online (Sandbox Code Playgroud)
然后启动失败:
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
Run Code Online (Sandbox Code Playgroud)
和一个空列表:
List of all partitions:
Run Code Online (Sandbox Code Playgroud)
所以根本无法识别磁盘。我还尝试使用 Debian ISO 安装程序安装的完全相同的内核,但对于 Debian,它以相同的方式失败,即使 Debian ISO 安装在相同的 QEMU 选项下运行良好(它生成 GRUB 安装在具有多个分区的磁盘中,根分区是ext4)。