在网上有没有预先构建的QEMU Ubuntu镜像(32位)?


你确定只能使用32位操作系统吗?这取决于CPU而已。 - Alvar
@Alvar 我不太确定。我的主机是Fedora 12,内核版本为2.6.29。我相信我的操作系统是32位的。处理器是Intel Core 2 Duo CPU E8400。我只是使用了命令"qemu-kvm -m 1024 img"。Img文件是从我提供的网站下载的。它在"loading initial ramdisk"这一步停止了... - Hao Shen
2是的,您的CPU具有64位兼容性。来源 - Alvar
4个回答

这个答案包含以下设置的详细步骤:
- 云镜像 amd64 和 arm64 - debootstrap amd64 和 arm64 - 桌面镜像 amd64
所有步骤都在针对 18.04 客户机的 Ubuntu 18.04 主机上进行了测试。
云镜像 amd64
Ubuntu 云镜像是预安装的镜像,允许您直接启动,而无需进行常规的桌面系统安装。另请参阅:https://serverfault.com/questions/438611/what-are-ubuntu-cloud-images
#!/usr/bin/env bash

sudo apt-get install cloud-image-utils qemu

# This is already in qcow2 format.
img=ubuntu-18.04-server-cloudimg-amd64.img
if [ ! -f "$img" ]; then
  wget "https://cloud-images.ubuntu.com/releases/18.04/release/${img}"

  # sparse resize: does not use any extra space, just allows the resize to happen later on.
  # https://superuser.com/questions/1022019/how-to-increase-size-of-an-ubuntu-cloud-image
  qemu-img resize "$img" +128G
fi

user_data=user-data.img
if [ ! -f "$user_data" ]; then
  # For the password.
  # https://stackoverflow.com/questions/29137679/login-credentials-of-ubuntu-cloud-server-image/53373376#53373376
  # https://serverfault.com/questions/920117/how-do-i-set-a-password-on-an-ubuntu-cloud-image/940686#940686
  # https://askubuntu.com/questions/507345/how-to-set-a-password-for-ubuntu-cloud-images-ie-not-use-ssh/1094189#1094189
  cat >user-data <<EOF
#cloud-config
password: asdfqwer
chpasswd: { expire: False }
ssh_pwauth: True
EOF
  cloud-localds "$user_data" user-data
fi

qemu-system-x86_64 \
  -drive "file=${img},format=qcow2" \
  -drive "file=${user_data},format=raw" \
  -device rtl8139,netdev=net0 \
  -enable-kvm \
  -m 2G \
  -netdev user,id=net0 \
  -serial mon:stdio \
  -smp 2 \
  -vga virtio \
;

GitHub upstream

在QEMU启动后,你可能需要按下回车键才能显示启动菜单。从中选择Ubuntu

然后,启动的开始部分如下:

error: no such device: root.

Press any key to continue...

但即使您不按任何键,启动会在短暂的超时后继续。请赞同此错误报告:https://bugs.launchpad.net/cloud-images/+bug/1726476

启动完成后,请使用以下登录:

  • 用户名:ubuntu
  • 密码:asdfqwer

互联网正常工作。

云镜像 arm64

待办事项:我注意到在使用这个时有时会出现一个错误:https://bugs.launchpad.net/cloud-images/+bug/1818197

与amd64非常相似,但我们需要一些UEFI黑魔法来引导它。

sudo apt-get install cloud-image-utils qemu-system-arm qemu-efi

# Get the image.
img=ubuntu-18.04-server-cloudimg-arm64.img
if [ ! -f "$img" ]; then
  wget "https://cloud-images.ubuntu.com/releases/18.04/release/${img}"
  qemu-img resize "$img" +128G
fi

# For the password.
user_data=user-data.img
if [ ! -f "$user_data" ]; then
  cat >user-data <<EOF
#cloud-config
password: asdfqwer
chpasswd: { expire: False }
ssh_pwauth: True
EOF
  cloud-localds "$user_data" user-data

  # Use the EFI magic. Picked up from:
  # https://wiki.ubuntu.com/ARM64/QEMU
  dd if=/dev/zero of=flash0.img bs=1M count=64
  dd if=/usr/share/qemu-efi/QEMU_EFI.fd of=flash0.img conv=notrunc
  dd if=/dev/zero of=flash1.img bs=1M count=64
fi

qemu-system-aarch64 \
  -M virt \
  -cpu cortex-a57 \
  -device rtl8139,netdev=net0 \
  -m 4096 \
  -netdev user,id=net0 \
  -nographic \
  -smp 4 \
  -drive "if=none,file=${img},id=hd0" \
  -device virtio-blk-device,drive=hd0 \
  -drive "file=${user_data},format=raw" \
  -pflash flash0.img \
  -pflash flash1.img \
;

GitHub上游

debootstrap amd64

不是预先制作的镜像,但它会下载所有预构建的软件包,因此速度也很快,而且更加可配置和有用。

#!/usr/bin/env bash

set -eux

debootstrap_dir=debootstrap
root_filesystem=debootstrap.ext2.qcow2

sudo apt-get install \
  debootstrap \
  libguestfs-tools \
  qemu-system-x86 \
;

if [ ! -d "$debootstrap_dir" ]; then
  # Create debootstrap directory.
  # - linux-image-generic: downloads the kernel image we will use under /boot
  # - network-manager: automatically starts the network at boot for us
  sudo debootstrap \
    --include linux-image-generic \
    bionic \
    "$debootstrap_dir" \
    http://archive.ubuntu.com/ubuntu \
  ;
  sudo rm -f "$root_filesystem"
fi

linux_image="$(printf "${debootstrap_dir}/boot/vmlinuz-"*)"

if [ ! -f "$root_filesystem" ]; then
  # Set root password.
  echo 'root:root' | sudo chroot "$debootstrap_dir" chpasswd

  # Remount root filesystem as rw.
  cat << EOF | sudo tee "${debootstrap_dir}/etc/fstab"
/dev/sda / ext4 errors=remount-ro,acl 0 1
EOF

  # Automaticaly start networking.
  # Otherwise network commands fail with:
  #     Temporary failure in name resolution
  # https://askubuntu.com/questions/1045278/ubuntu-server-18-04-temporary-failure-in-name-resolution/1080902#1080902
  cat << EOF | sudo tee "$debootstrap_dir/etc/systemd/system/dhclient.service"
[Unit]
Description=DHCP Client
Documentation=man:dhclient(8)
Wants=network.target
Before=network.target
[Service]
Type=forking
PIDFile=/var/run/dhclient.pid
ExecStart=/sbin/dhclient -4 -q
[Install]
WantedBy=multi-user.target
EOF
  sudo ln -sf "$debootstrap_dir/etc/systemd/system/dhclient.service" \
    "${debootstrap_dir}/etc/systemd/system/multi-user.target.wants/dhclient.service"

  # Why Ubuntu, why.
  # https://bugs.launchpad.net/ubuntu/+source/linux/+bug/759725
  sudo chmod +r "${linux_image}"

  # 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

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_image}" \
  -device rtl8139,netdev=net0 \
  -netdev user,id=net0 \
;

GitHub上游

这个启动没有任何systemd错误或警告。

现在从终端登录,使用root / root进行登录,然后使用以下命令检查互联网是否正常工作:

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

我们使用了nc,如https://stackoverflow.com/questions/32341518/how-to-make-an-http-get-request-manually-with-netcat/52662497#52662497所解释的原因是:

类似的Debian版本:https://unix.stackexchange.com/questions/275429/creating-bootable-debian-image-with-debootstrap/473256#473256

构建自己的内核

既然我们在这里:

git clone git://kernel.ubuntu.com/ubuntu/ubuntu-bionic.git
cd ubuntu-bionic
# Tag matches the working kernel that debootstrap downloaded for us.
git checkout Ubuntu-4.15.0-20.21
fakeroot debian/rules clean
debian/rules updateconfigs
fakeroot debian/rules build-generic
linux_image="$(pwd)/debian/build/build-generic/arch/x86_64/boot/bzImage"

这将生成与已打包的Ubuntu完全相同的配置文件,并且我相信使用的源代码也完全相同,就像在哪里获取11.04内核.config文件?中解释的那样从debootstrap下载的一样。

然后我进行了补丁:

diff --git a/init/main.c b/init/main.c
index b8b121c17ff1..542229349efc 100644
--- a/init/main.c
+++ b/init/main.c
@@ -516,6 +516,8 @@ asmlinkage __visible void __init start_kernel(void)
        char *command_line;
        char *after_dashes;

+ pr_info("I'VE HACKED THE LINUX KERNEL!!!");
+
        set_task_stack_end_magic(&init_task);
        smp_setup_processor_id();
        debug_objects_early_init();

重新建立:
fakeroot debian/rules build-generic

并且它在启动过程中打印了我的消息:
I'VE HACKED THE LINUX KERNEL!!!

重建过程虽然不太快,也许有更好的命令?我只是等待它显示:
Kernel: arch/x86/boot/bzImage is ready  (#3)

并继续进行了运行。
debootstrap arm64
该过程与amd64类似,但有以下区别:
1)
我们必须进行两个阶段的debootstrap:
首先使用--foreign只下载软件包 然后将QEMU静态安装到chroot中 然后我们使用QEMU用户模式仿真+ binfmt_misc进行软件包安装的第二阶段
另请参阅:什么是debootstrap --second-stage 默认内核引导在最后失败,显示以下错误信息: [ 0.773665] 请添加正确的 "root=" 引导选项;以下是可用的分区列表: [ 0.774033] 内核恐慌 - 无法同步:VFS:无法挂载未知块(0,0)上的根文件系统
空的分区列表表明磁盘驱动程序存在严重错误,在尝试了一段时间后,发现缺失的选项是:
CONFIG_VIRTIO_BLK=y

我觉得使用ISO时它能够工作,因为模块必须从initrd中加载。

我尝试使用其他磁盘类型,但virtio是-drive if=的唯一有效值,当-M virt时,这是现在更合理的机器类型。

因此,我们必须重新编译自己的内核,并启用该选项,如此处所述:交叉编译内核时,如何阻止每次都进行完整编译,而只想修改一个文件?

Ubuntu开发人员应默认启用此CONFIG y!它非常有用!

待办事项:网络不工作,错误消息如下:

root@ciro-p51:~# systemctl status dhclient.service
root@ciro-p51:~# cat f
● dhclient.service - DHCP Client
   Loaded: loaded (/etc/systemd/system/dhclient.service; enabled; vendor preset: enabled)
   Active: failed (Result: protocol) since Sun 2018-01-28 15:58:42 UTC; 2min 2s ago
     Docs: man:dhclient(8)
  Process: 171 ExecStart=/sbin/dhclient -4 -q (code=exited, status=0/SUCCESS)

Jan 28 15:58:40 ciro-p51 systemd[1]: Starting DHCP Client...
Jan 28 15:58:42 ciro-p51 dhclient[171]: No broadcast interfaces found - exiting.
Jan 28 15:58:42 ciro-p51 systemd[1]: dhclient.service: Can't open PID file /var/run/dhclient.pid (yet?) after start: No such file or directory
Jan 28 15:58:42 ciro-p51 systemd[1]: dhclient.service: Failed with result 'protocol'.
Jan 28 15:58:42 ciro-p51 systemd[1]: Failed to start DHCP Client.

这是完全自动化的脚本:
#!/usr/bin/env bash

# https://askubuntu.com/questions/281763/is-there-any-prebuilt-qemu-ubuntu-image32bit-online/1081171#1081171

set -eux

debootstrap_dir=debootstrap
root_filesystem=debootstrap.ext2.qcow2

sudo apt-get install \
  gcc-aarch64-linux-gnu \
  debootstrap \
  libguestfs-tools \
  qemu-system-aarch64 \
  qemu-user-static \
;

if [ ! -d "$debootstrap_dir" ]; then
  sudo debootstrap \
    --arch arm64 \
    --foreign \
    bionic \
    "$debootstrap_dir" \
    http://ports.ubuntu.com/ubuntu-ports \
  ;
  sudo mkdir -p "${debootstrap_dir}/usr/bin"
  sudo cp "$(which qemu-aarch64-static)" "${debootstrap_dir}/usr/bin"
  sudo chroot "$debootstrap_dir" /debootstrap/debootstrap --second-stage
  sudo rm -f "$root_filesystem"
fi

linux_image="$(printf "${debootstrap_dir}/boot/vmlinuz-"*)"

if [ ! -f "$root_filesystem" ]; then
  # Set root password.
  echo 'root:root' | sudo chroot "$debootstrap_dir" chpasswd

  # Remount root filesystem as rw.
  cat << EOF | sudo tee "${debootstrap_dir}/etc/fstab"
/dev/sda / ext4 errors=remount-ro,acl 0 1
EOF

  # Automaticaly start networking.
  # Otherwise network commands fail with:
  #     Temporary failure in name resolution
  # https://askubuntu.com/questions/1045278/ubuntu-server-18-04-temporary-failure-in-name-resolution/1080902#1080902
  cat << EOF | sudo tee "${debootstrap_dir}/etc/systemd/system/dhclient.service"
[Unit]
Description=DHCP Client
Documentation=man:dhclient(8)
Wants=network.target
Before=network.target

[Service]
Type=forking
PIDFile=/var/run/dhclient.pid
ExecStart=/sbin/dhclient -4 -q

[Install]
WantedBy=multi-user.target
EOF
  sudo ln -sf "${debootstrap_dir}/etc/systemd/system/dhclient.service" \
    "${debootstrap_dir}/etc/systemd/system/multi-user.target.wants/dhclient.service"

  # Why Ubuntu, why.
  # https://bugs.launchpad.net/ubuntu/+source/linux/+bug/759725
  sudo chmod +r "${linux_image}"

  # 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

# Build the Linux kernel.
linux_image="$(pwd)/linux/debian/build/build-generic/arch/arm64/boot/Image"
if [ ! -f "$linux_image" ]; then
  git clone --branch Ubuntu-4.15.0-20.21 --depth 1 git://kernel.ubuntu.com/ubuntu/ubuntu-bionic.git linux
  cd linux
patch -p1 << EOF
diff --git a/debian.master/config/config.common.ubuntu b/debian.master/config/config.common.ubuntu
index 5ff32cb997e9..8a190d3a0299 100644
--- a/debian.master/config/config.common.ubuntu
+++ b/debian.master/config/config.common.ubuntu
@@ -10153,7 +10153,7 @@ CONFIG_VIDEO_ZORAN_ZR36060=m
 CONFIG_VIPERBOARD_ADC=m
 CONFIG_VIRTIO=y
 CONFIG_VIRTIO_BALLOON=y
-CONFIG_VIRTIO_BLK=m
+CONFIG_VIRTIO_BLK=y
 CONFIG_VIRTIO_BLK_SCSI=y
 CONFIG_VIRTIO_CONSOLE=y
 CONFIG_VIRTIO_INPUT=m
EOF
  export ARCH=arm64
  export $(dpkg-architecture -aarm64)
  export CROSS_COMPILE=aarch64-linux-gnu-
  fakeroot debian/rules clean
  debian/rules updateconfigs
  fakeroot debian/rules DEB_BUILD_OPTIONS=parallel=`nproc` build-generic
  cd -
fi

qemu-system-aarch64 \
  -append 'console=ttyAMA0 root=/dev/vda rootfstype=ext2' \
  -device rtl8139,netdev=net0 \
  -drive "file=${root_filesystem},format=qcow2" \
  -kernel "${linux_image}" \
  -m 2G \
  -netdev user,id=net0 \
  -serial mon:stdio \
  -M virt,highmem=off \
  -cpu cortex-a57 \
  -nographic \
;

GitHub Upstream

桌面图像

参见:如何在QEMU上运行Ubuntu桌面?

虽然需要手动安装程序,但这是你可以做的最稳定的事情,如果你只是想偶尔运行一个交互式使用的虚拟机,那完全没问题。

至于aarch64,我还没有让桌面工作起来,也许你可以关注一下:如何在QEMU上运行Ubuntu 16.04 ARM?

Debian aarch64

https://gist.github.com/philipz/04a9a165f8ce561f7ddd并将sudo mount /dev/nbd0p2更改为nbd0p1


1我稍微修改了你的脚本:https://gist.github.com/lnyng/8342947a1d5455303fd8730c9ca35da0 主要的改动是创建了一个dhclient systemd单元,以避免安装network-manager,这需要许多与UI相关的库(对于我的安装来说大约300+MB)。 - lnyng
@lyang 谢谢!又一次让我不用好好学习systemd了 :-) - Ciro Santilli OurBigBook.com
@lyang,按照更新的答案所述尝试使用arm64时,我遇到了错误:dhclient.service: Can't open PID file /var/run/dhclient.pid (yet?) after start: No such file or directory,有什么线索吗?启动后我可以执行touch /var/run/a - Ciro Santilli OurBigBook.com
似乎是一个权限错误。也许将pid路径更改为其他位置,比如/tmp/dhclient.pid?或者如果我们并不真的关心终止该进程,可以直接将其删除... - lnyng
2谢谢!这个回答真的帮了很多。 - jakob.j

一个快速的谷歌搜索揭示了以下内容(我没有尝试过其中任何一个): 此外,您还可以使用vmbuilder(在这里称为ubuntu-vmbuilder)快速创建适用于KVM、VirtualBox等的Ubuntu镜像。
作为最后的手段,您可以使用qemu-img命令将来自VirtualBox/VMware的磁盘映像转换为更适合QEMU/KVM的格式(可能不需要:我认为QEMU/KVM可以处理其他类型的映像,如vdi或vmdk)。
$ qemu-img convert -f [vdi|vmdk|...] -O qcow2 OriginalImage NewImage

注意:如果您使用的是32位操作系统,则无法在KVM上运行64位虚拟机。但是QEMU是一个模拟器,所以它应该可以让您在32位操作系统上运行64位虚拟机。但是性能开销可能会非常大!


1那么,你如何使用这些图片呢?更准确地说,你如何登录? - Frederick Nord
您可以通过cloud-init添加您的ssh密钥。 - Dilip Renkila
1@FrederickNord 登录 https://stackoverflow.com/questions/29137679/login-credentials-of-ubuntu-cloud-server-image/54440564#54440564 - rofrol

https://www.turnkeylinux.org/存在已经很久了。他们有一个庞大的可下载的预制“应用程序”图像目录,具有多种格式(ova、iso、vdmk、openstack、xen)。他们甚至可以在AWS上为您启动一个图像。

当我想要开始探索特定的堆栈或解决问题时,我经常会下载他们的图像之一,将其转换为cow2并使用它。

您还可以从https://app.vagrantup.com/boxes/searchhttps://virtualboxes.org/images/获取图像并进行转换。