A quick script for bootstrapping QEMU Alpine VM's with USB drive passthrough on OpenBSD host systems

For a stupid and useless project of mine (running OpenBSD on the 1st gen Apple TV) I need to be able to run a few linux-specific partitioning commands; like setting custom partition flags. OpenBSD doesn't do those, so I needed a VM.

The built-in, otherwise excellent `vmd` cannot pass through devices (yet), so I cannot access the AppleTV's HDD attached via an USB adadpter. Qemu can, however. But to get Qemu to boot my VM was a bit of a hassle - far less straightforward than `vmd`, so I thought I'd share my startup script, with some explanations to follow.

Startup script

startalpine.sh:

#!/bin/sh
xhost +SI:localuser:root
ulimit -Sd `ulimit -Hd`
doas qemu-system-x86_64 \
	-cpu max \
	-cdrom ~/path-to-alpine-virt-cd-image.iso
	-drive if=virtio,file=/home/kls/VM/alpine-qemu.qcow2 \
	-drive if=virtio,file=/dev/rsd4c,format=raw \
	-m 2048 \
	-smp 2 \
	-display sdl \
	-netdev user,id=net0,ipv6=off \
	-device virtio-net,netdev=net0 \
	-boot d
xhost -SI:localuser:root

Solving the initial kernel panic (we cannot have nice things)

Because of the fall of Adam and Eve and the introduction of corruption, death, decay, and sin into the created order, the VM won't just start. Oh no. It will die with a kernel panic, if you are me.

When you just hit "enter" at the boot prompt, it tells me,

boot:
[    0.005000] Kernel panic - not syncing: IO-APIC + timer doesn't work!  Boot w
ith apic=debug and send a report.  Then try booting with the 'noapic' option.
[    0.005000] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.12.51-0-virt #
1-Alpine
[    0.005000] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1
.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
[    0.005000] Call Trace:
[    0.005000]  
[    0.005000]  dump_stack_lvl+0x5d/0x90
[    0.005000]  panic+0x113/0x2d6
[    0.005000]  setup_IO_APIC+0xc08/0xd20
[    0.005000]  ? _raw_spin_unlock_irqrestore+0x1c/0x50
[    0.005000]  ? clear_IO_APIC_pin+0x120/0x1f0
[    0.005000]  apic_intr_mode_init+0x1ba/0x1e0
[    0.005000]  x86_late_time_init+0x3e/0xa0
[    0.005000]  start_kernel+0x6ab/0x750
[    0.005000]  x86_64_start_reservations+0x24/0x30
[    0.005000]  x86_64_start_kernel+0x75/0x80
[    0.005000]  common_startup_64+0x13b/0x148
[    0.005000]  
[    0.005000] ---[ end Kernel panic - not syncing: IO-APIC + timer doesn't work
!  Boot with apic=debug and send a report.  Then try booting with the 'noapic' o
ption. ]---

So first you want to see what bootable images there are. Press "TAB" at the boot prompt REAL quick on startup. For the "virt" image that Alpine distributes for ...virt..ual machines, the boot option is, you guessed it,

virt

So at the boot prompt you want:

boot: virt noapic

And miracle of miracles, it will oblige and boot.

Alpine setup

Login as `root`, then run setup-alpine, it is fairly painless, and refreshingly resembling the OpenBSD installer.

To fix the bootup issue, you need to add "noapic" to the default boot options.

As root, edit `/etc/update-extlinux.conf` and to the line for "default_kernel_options" append "noapic". For me, that looks like:

default_kernel_options="quiet rootfstype=ext4 noapic"

This is it really. The device I wanted to poke around with is listed under /dev/vdb, as well as its partitions. I call this a success.

EOT