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
- xhost +SI etc: we are letting root use our X11 displays, otherwise we get all sorts of authorization errors from SDL or GTK.
- ulimit: So first, "ulimit" -- one must increase the default RAM allocatable. If your user is a member of the `staff` group, this is "infinity". That is nice, because 2Gb is smaller than infinity.
- doas qemu-system-x86_64: this is the type of emulated system I want to run. I am starting qemu with doas here because the original user running the X session needs to grant root the rights to use its display server.
- -cpu max: enable ALL THE EMULATION FEATURES the cpu has (because I don't really know what I am doing so it seems like a good idea)
- -cdrom: the path to the ISO file. This is the "virt" iso for installation. after installation, remove this line.
- -drive (1): the first is the qcow disk image for the system that we will install to.
- -drive (2): this is the device passthrough bit. Because OpenBSD does not allow access to its devices for randos like the standard user, when we want device passthrough to work, we need to start the VM as root. Usually a very bad idea.
- -m: how many kilograms of RAM
- -smp: something to do with the Scottish Mational Party or with cpu's and stuff, idunno
- -display: change this to `curses` for copypastability
- -netdev, device: networking stuff I copypasted from somewhere, it works
- -boot c: this tells the VM to boot from the CD rom; change this to "boot c" after install to boot from first available HDD
- xhost -SI etc: revoking root's X11 privileges on quit.
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