#!/bin/sh -e # run-hurd.sh, a script to fetch and run Debian GNU (Hurd) using qemu, aspiring to be fool-proof # Copyright (C) 2026 alicia@ion.nu # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . bit64=false redownload=false fsck=false daemon=false expand='' while getopts "6rfde:" opt; do case "$opt" in 6) bit64=true;; r) redownload=true;; f) fsck=true;; d) daemon=true;; e) expand="$OPTARG" if ! echo "$expand" | grep -q '[0-9]\+[BKMGTP]'; then echo 'Invalid format for expansion. Expected number followed by unit (B for bytes, K for kilobytes, M for megabytes etc.)' exit 1 fi;; *) echo "Usage: ${0} [options]" echo 'Options include:' echo ' -6 = use the new 64bit build' echo ' -r = redownload instead of booting existing image' echo ' -f = run a filesystem check (requires losetup and fsck.ext2)' echo ' -d = daemonize, start qemu and return to the shell' echo ' -e = expand disk image to the given size' # TODO: option for curses display (for non-GUI environments and/or to translate keyboard because Hurd console currently lacks keyboard layouts outside US qwerty) # TODO: option for VNC display exit;; esac done if [ ! -e debian-hurd.img ] || "$redownload"; then rm -f debian-hurd.img.tar.gz if "$bit64"; then wget 'https://cdimage.debian.org/cdimage/ports/latest/hurd-amd64/debian-hurd.img.tar.gz' else wget 'https://cdimage.debian.org/cdimage/ports/latest/hurd-i386/debian-hurd.img.tar.gz' fi image="`tar -xvzf debian-hurd.img.tar.gz`" mv "$image" debian-hurd.img fi if "$fsck"; then # TODO: Dynamically figure out which way (if any, maybe user is root) to run these as root disk="`sudo losetup -fP --show debian-hurd.img`" if [ -z "$disk" ]; then echo 'Failed to losetup the disk image. Is losetup installed?'; exit 1; fi if [ -e "${disk}p5" ]; then sudo fsck.ext2 -fy "${disk}p5" else sudo fsck.ext2 -fy "${disk}p2" # 32bit doesn't use the extended partition fi sudo losetup -d "$disk" fi if [ -n "$expand" ]; then num="`echo "$expand" | sed -e 's/[A-Z]$//'`" unit="`echo "$expand" | sed -e 's/^[0-9]*//'`" dd if=/dev/zero of=debian-hurd.img bs="1${unit}" count=0 seek="$num" disk="`sudo losetup -fP --show debian-hurd.img`" # TODO: Unify the losetup calls? if [ -z "$disk" ]; then echo 'Failed to losetup the disk image. Is losetup installed?'; exit 1; fi sudo parted "$disk" resizepart 2 '100%' # Resize the extended partition sudo parted "$disk" resizepart 5 '100%' || true # Resize the filesystem's partition therein (unless it's 32bit and doesn't have the extended partition) if [ -e "${disk}p5" ]; then sudo resize2fs "${disk}p5" else sudo resize2fs "${disk}p2" fi sudo losetup -d "$disk" fi runqemu() { kvm="`grep -q ' \(svm\|vmx\)' /proc/cpuinfo && echo '--enable-kvm'`" # I think 32bit code should work even if we run x86_64 qemu? # From some testing, it appears -M q35 is not needed for 64bit Hurd, but breaks 32bit Hurd. Therefor omitting it qemu-system-x86_64 ${kvm} -m 2G -drive cache=writeback,file=debian-hurd.img -net user,hostfwd=tcp:127.0.0.1:2222-:22 -net nic,model=e1000 } if "$daemon"; then runqemu > /dev/null 2> /dev/null & else runqemu fi