#!/usr/bin/env bash set -e LOG=/tmp/qemu.log LOCK=/tmp/qemu.lock if [ -n "${CROSS_DEBUG}" ]; then set -x fi # arch in the rust target arch="${1}" shift if [ "${CROSS_RUNNER}" = "" ]; then if [[ "${arch}" == i?86 ]] || [[ "${arch}" == x86_64 ]]; then CROSS_RUNNER=native else CROSS_RUNNER=qemu-user fi fi # select qemu arch qarch="${arch}" case "${arch}" in armv7) qarch="arm" ;; i686) qarch="i386" ;; powerpc) qarch="ppc" ;; powerpc64) qarch="ppc64" ;; powerpc64le) if [ "${CROSS_RUNNER}" = "qemu-user" ]; then qarch="ppc64le" else qarch="ppc64" fi ;; esac case "${CROSS_RUNNER}" in native) exec "${@}" ;; qemu-user) exec "qemu-${qarch}" "${@}" ;; qemu-system) true ;; *) echo "Invalid runner: \"${CROSS_RUNNER}\""; echo "Valid runners are: native, qemu-user and qemu-system" exit 1 ;; esac n="$(nproc)" memory=1G driver9p="virtio-9p-pci" drivernet="virtio-net-pci" # select qemu parameters case "${arch}" in aarch64) # 8 is the max number of cpu supported by qemu-aarch64 n=$(( n > 8 ? 8 : n )) opt="-machine virt -cpu cortex-a57" ;; armv7) opt="-machine virt" driver9p="virtio-9p-device" drivernet="virtio-net-device" ;; i686) opt="-append console=ttyS0" ;; mips|mipsel) # avoid kernel error # https://blahcat.github.io/2017/07/14/building-a-debian-stretch-qemu-image-for-mipsel/ opt="-append nokaslr" n=1 ;; mips64el) # avoid kernel error # https://blahcat.github.io/2017/07/14/building-a-debian-stretch-qemu-image-for-mipsel/ opt="-append nokaslr -cpu MIPS64R2-generic" n=1 ;; powerpc) opt="-append console=ttyPZ0" n=1 ;; powerpc64|powerpc64le) opt="-append console=hvc0 --nodefaults -serial stdio" ;; s390x) n=1 driver9p="virtio-9p-ccw" drivernet="virtio-net-ccw" ;; sparc64) n=1 driver9p+=",bus=pciB" drivernet+=",bus=pciB" ;; x86_64) opt="-append console=ttyS0" ;; esac ( flock -n 200 || exit 0 echo Booting QEMU virtual machine with $n cpus... QEMU_CMD="qemu-system-${qarch} \ -m ${memory} \ -smp ${n} \ -nographic \ -monitor none \ -netdev user,id=net0,hostfwd=tcp::10022-:22 \ -device ${drivernet},netdev=net0 \ -kernel /qemu/kernel \ -initrd /qemu/initrd.gz \ ${opt} \ -fsdev local,id=fs0,path=/target,security_model=mapped \ -device ${driver9p},fsdev=fs0,mount_tag=target" touch "${LOG}" if [[ -n "${CROSS_DEBUG}" ]]; then (${QEMU_CMD} 2>&1 | tee -a "${LOG}") & else ${QEMU_CMD} >> "${LOG}" 2>&1 & fi # wait for dropbear for _ in $(seq 240); do if grep -q "Not backgrounding" "${LOG}"; then READY=1 break fi sleep 0.5s done if [ -z "${READY}" ]; then if [ -n "${CROSS_DEBUG}" ]; then echo "Not ready but continuing because CROSS_DEBUG is set" else echo "Qemu is not ready after ${SECONDS} seconds..." echo "Set the environment variable CROSS_DEBUG=1 to debug" echo "Last 100 lines of qemu output:" tail -n 100 "${LOG}" exit 1 fi fi echo "Booted in ${SECONDS} seconds" ) 200>"${LOCK}" if [[ -t 1 ]] && [[ -t 2 ]]; then tty_flag='-t' fi exec dbclient ${tty_flag} -p 10022 -y -y root@localhost "${@}"