timdoug's tidbits
2017-06-01
Installing Debian in xhyve
xhyve is a nice and lightweight hypervisor for macOS. Getting Debian running on it requires a bit of effort though; the following instructions result in a functional installation with working networking.
- git clone https://github.com/mist64/xhyve.git
- Apply this patch so there's enough space for the installer ramdisk (thanks to this PR for the tip):
diff --git a/src/firmware/kexec.c b/src/firmware/kexec.c
index 61aeebb..2a5ce67 100644
--- a/src/firmware/kexec.c
+++ b/src/firmware/kexec.c
@@ -184,7 +184,7 @@ kexec_load_ramdisk(char *path) {
sz = (size_t) ftell(f);
fseek(f, 0, SEEK_SET);
- ramdisk_start = ALIGNUP((kernel.base + kernel.size), 0x1000ull);
+ ramdisk_start = ALIGNUP((kernel.base + kernel.size + 32*1024*1024), 0x1000ull);
if ((ramdisk_start + sz) > memory.size) {
/* not enough memory */
- make
- Grab the Debian installer kernel and initrd. I use the daily snapshots, but substitute accordingly.
curl https://d-i.debian.org/daily-images/amd64/daily/netboot/debian-installer/amd64/initrd.gz -o initrd.gz-installer
curl https://d-i.debian.org/daily-images/amd64/daily/netboot/debian-installer/amd64/linux -o linux-installer
- Create an empty disk image: dd if=/dev/zero of=debian.img bs=1m count=8192
- Grab a UUID so the VM comes up with the same IP address every launch: python -c 'import uuid; print uuid.uuid4()'
- Run the Debian installer, changing options accordingly (1G is RAM size, the arguments to virtio-blk and the kexec firmware are paths): sudo ./build/xhyve -A -H -U <<<YOUR UUID HERE>>> -m 1G -s 0,hostbridge -s 1,lpc -s 2,virtio-blk,debian.img -s 3,virtio-net -l com1,stdio -f "kexec,linux-installer,initrd.gz-installer,earlyprintk=serial console=ttyS0" Feel free to skip bootloader installation, since we use xhyve's kexec implementation.
- We now need to grab the non-installer kernel and initrd out of the disk image.
- Boot into the installer's recovery mode by passing rescue/enable=true:
sudo ./build/xhyve -A -H -U <<<YOUR UUID HERE>>> -m 1G -s 0,hostbridge -s 1,lpc -s 2,virtio-blk,debian.img -s 3,virtio-net -l com1,stdio -f "kexec,linux-installer,initrd.gz-installer,earlyprintk=serial console=ttyS0 rescue/enable=true"
- Use /dev/vda1 as the root filesystem and execute a shell there (both the defaults), then type bash to get a sane one.
- apt-get install netcat
- On the host run nc -l 8000 >vmlinuz, and on the VM run nc 192.168.64.1 8000 </boot/vmlinuz*. You'll have to manually ctrl-C after the (essentially instant) transfer is complete.
- Do the same for the initrd.img in /boot.
- Verify checksums and sanity otherwise:
host$ file vmlinuz initrd.img
vmlinuz: Linux kernel x86 boot executable bzImage, version 4.9.0-3-amd64 (debian-kernel@lists.debian.org) #1 SMP Debian 4., RO-rootFS, swap_dev 0x3, Normal VGA
initrd.img: gzip compressed data, last modified: Thu Jun 1 16:23:39 2017, from Unix
host$
- Exit out of bash and the chroot, then "reboot" the system.
- Start your new VM, being sure to change the kernel/initrd paths and set the root partition's location accordingly: sudo ./build/xhyve -A -H -U <<<YOUR UUID HERE>>> -m 1G -s 0,hostbridge -s 1,lpc -s 2,virtio-blk,debian.img -s 3,virtio-net -l com1,stdio -f "kexec,vmlinuz,initrd.img,earlyprintk=serial console=ttyS0 root=/dev/vda1"
- Success! Install an SSH server, get work done, etc.
Other notes:
- I know xhyve and Hypervisor.framework don't require root privileges, but the virtio-net implementation does. I haven't tried using a TUN/TAP device.
- Little Snitch, mDNSResponder, and xhyve have some sort of interaction that (at least with my configuration) requires explicit incoming/outgoing DNS access, otherwise it silently prevents networking from working. Once I whitelist the client IP and UDP/53 in my firewall rules, names are successfully resolved.
[/osx]
permanent link