1#!/bin/sh 2########################################################################## 3# Copyright (c) 2009-2015 ETH Zurich. 4# All rights reserved. 5# 6# This file is distributed under the terms in the attached LICENSE file. 7# If you do not find this file, copies can be found by writing to: 8# ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich, 9# Attn: Systems Group. 10# 11# Shell script for running Qemu with a Barrelfish image 12# 13########################################################################## 14 15HDFILE=hd.img 16EFI_FLASH0=flash0.img 17EFI_FLASH1=flash1.img 18HAGFISH_LOCATION="/home/netos/tftpboot/Hagfish.efi" 19MENUFILE="" 20ARCH="" 21DEBUG_SCRIPT="" 22BIOS="/home/netos/tftpboot/QEMU_EFI.fd" 23# Grab SMP from env, if unset default to 1 24SMP=${SMP:-4} 25# Grab the MEMORY from the enf 26MEMORY=${MEMORY:-4G} 27# Grab the KVM fenable from the env 28KVM=${KVM:-"-enable-kvm"} 29 30# Grab NIC_MODEL from env, if unset default to e1000 31NIC_MODEL="${NIC_MODEL:-e1000}" 32# U-Boot options 33UBOOT=false 34UBOOT_IMAGE=/home/netos/tftpboot/u-boot.bin 35 36 37usage () { 38 echo "Usage: $0 --menu <file> --arch <arch> [options]" 39 echo " where:" 40 echo " 'arch' is one of: x86_64, a15ve, armv8, zynq7" 41 echo " 'file' is a menu.lst format file to read module list from" 42 echo " and options can be:" 43 echo " --debug <script> (run under the specified GDB script)" 44 echo " --hdfile <file> (hard disk image to be build for AHCI, defaults to $HDFILE" 45 echo " --kernel <file> (kernel binary, if no menu.lst given)" 46 echo " --initrd <file> (initial RAM disk, if no menu.lst given)" 47 echo " --image <file> (prebaked boot image, instead of kernel/initrd)" 48 echo " --args <args> (kernel command-line args, if no menu.lst given)" 49 echo " --smp <cores> (number of cores to use, defaults to $SMP)" 50 echo " --nic-model <name> (nic model to use, defaults to $NIC_MODEL)" 51 echo " --hagfish <file> (Hagfish boot loader, defaults to $HAGFISH_LOCATION)" 52 echo " --bios <file> (ARMv8 QEMU bios, defaults to $BIOS)" 53 echo " --uboot (boot U-Boot instead of EFI on ARMv8)" 54 echo " --uboot-img <file> (U-Boot binary, defaults to $UBOOT_IMAGE)" 55 echo " " 56 echo " The following environment variables are considered:" 57 echo " QEMU_PATH (Path for qemu-system-* binary)" 58 echo " NIC_MODEL (Same as --nic-model)" 59 echo " SMP (Same as --smp)" 60 exit 1 61} 62 63# Result in $? 64qemu_supports_device() { 65 ${QEMU_PATH}qemu-system-x86_64 -device help 2>&1 | grep \"$1\" > /dev/null 66} 67 68 69if test $# = 0; then usage ; fi 70while test $# != 0; do 71 case $1 in 72 "--help"|"-h") 73 usage 74 exit 0 75 ;; 76 "--menu") 77 shift; MENUFILE="$1" 78 ;; 79 "--arch") 80 shift; ARCH="$1" 81 ;; 82 "--hdfile") 83 shift; HDFILE="$1" 84 ;; 85 "--debug") 86 shift; DEBUG_SCRIPT="$1" 87 ;; 88 "--initrd") 89 shift; INITRD="$1" 90 ;; 91 "--kernel") 92 shift; KERNEL="$1" 93 ;; 94 "--image") 95 shift; IMAGE="$1" 96 ;; 97 "--args") 98 shift; KERNEL_CMDS="$1" 99 ;; 100 "--smp") 101 shift; SMP="$1" 102 ;; 103 "--hagfish") 104 shift; HAGFISH_LOCATION="$1" 105 ;; 106 "--bios") 107 shift; BIOS="$1" 108 ;; 109 "--nic-model") 110 shift; NIC_MODEL="$1" 111 ;; 112 "--uboot") 113 UBOOT=true 114 ;; 115 "--uboot-img") 116 UBOOT=true 117 shift; UBOOT_IMAGE="$1" 118 ;; 119 *) 120 echo "Unknown option $1 (try: --help)" >&2 121 exit 1 122 ;; 123 esac 124 shift 125done 126 127if test -z "$IMAGE"; then 128 if test -z "$MENUFILE"; then 129 echo "No menu.lst file specified." 130 if test -z "$KERNEL"; then 131 echo "ERROR: No initial kernel given and no menu.lst file." >&2; exit 1 132 fi 133 if test -z "$INITRD"; then 134 echo "ERROR: No initial RAM disk given and no menu.lst file." >&2; exit 1 135 fi 136 else 137 echo "Using menu file $MENUFILE" 138 ROOT=`sed -rne 's,^root[ \t]*([^ ]*).*,\1,p' "$MENUFILE"` 139 if test "$ROOT" != "(nd)"; then 140 echo "Root: $ROOT" 141 fi 142 KERNEL=`sed -rne 's,^kernel[ \t]*/([^ ]*).*,\1,p' "$MENUFILE"` 143 if test "$ROOT" != "(nd)"; then 144 KERNEL="$ROOT/$KERNEL" 145 fi 146 if test -z "$KERNEL"; then 147 echo "ERROR: No initial kernel specified in menu.lst file." >&2; exit 1 148 fi 149 KERNEL_CMDS=`sed -rne 's,^kernel[ \t]*[^ ]*[ \t]*(.*),\1,p' "$MENUFILE"` 150 if test "$ROOT" != "(nd)"; then 151 AWKSCRIPT='{ if (NR == 1) printf(root "/" $$0); else printf("," root "/" $$0) }' 152 AWKARGS="-v root=$ROOT" 153 else 154 AWKSCRIPT='{ if (NR == 1) printf($$0); else printf("," $$0) }' 155 fi 156 INITRD=`sed -rne 's,^module(nounzip)?[ \t]*/(.*),\2,p' "$MENUFILE" | awk $AWKARGS "$AWKSCRIPT"` 157 if test -z "$INITRD"; then 158 echo "ERROR: No initial ram disk modules specified in menu.lst file." >&2; exit 1 159 fi 160 fi 161 echo "Initial kernel file: $KERNEL" 162 echo "Initial RAM disk contents: $INITRD" 163else 164 echo "Booting image: $IMAGE" 165fi 166 167echo "Kernel command line arguments: $KERNEL_CMDS" 168echo "Requested architecture is $ARCH." 169 170case "$ARCH" in 171 "x86_64") 172 qemu_supports_device $NIC_MODEL 173 if [ $? = 1 ] ; then 174 echo "$NIC_MODEL not supported. Fall back to e1000" 175 NIC_MODEL=e1000 ; 176 fi 177 178 # Two NIC qemu conf 179 #QEMU_CMD="${QEMU_PATH}qemu-system-x86_64 \ 180 # -machine type=q35 \ 181 # -smp $SMP \ 182 # -enable-kvm \ 183 # -m 1024 \ 184 # -netdev user,id=network0 \ 185 # -netdev user,id=network1 \ 186 # -device $NIC_MODEL,netdev=network0 187 # -device $NIC_MODEL,netdev=network1 188 # -device ahci,id=ahci \ 189 # -device ide-drive,drive=disk,bus=ahci.0 \ 190 # -drive id=disk,file="$HDFILE",if=none" 191 192 QEMU_CMD="${QEMU_PATH}qemu-system-x86_64 \ 193 -machine type=q35 \ 194 -smp ${SMP} \ 195 -m ${MEMORY} \ 196 ${KVM} \ 197 -netdev user,id=network0 \ 198 -device $NIC_MODEL,netdev=network0 \ 199 -device ahci,id=ahci \ 200 -device ide-drive,drive=disk,bus=ahci.0 \ 201 -drive id=disk,file="$HDFILE",if=none" 202 QEMU_NONDEBUG=-nographic 203 GDB=gdb-multiarch 204 echo "Creating hard disk image $HDFILE" 205 qemu-img create "$HDFILE" 10M 206 ;; 207 "a15ve") 208 QEMU_CMD="${QEMU_PATH}qemu-system-arm \ 209 -m 2G \ 210 -smp $SMP \ 211 -machine vexpress-a15" 212 GDB=gdb 213 QEMU_NONDEBUG=-nographic 214 ;; 215 "armv8") 216 QEMU_CMD="${QEMU_PATH}qemu-system-aarch64 \ 217 -m ${MEMORY} \ 218 -cpu cortex-a57 \ 219 -M virt -d guest_errors \ 220 -M gic_version=3 \ 221 -smp ${SMP}" 222 if $UBOOT; then 223 QEMU_CMD="$QEMU_CMD -bios $UBOOT_IMAGE \ 224 -device loader,addr=0x50000000,file=$IMAGE" 225 else 226 QEMU_CMD="$QEMU_CMD -bios $BIOS \ 227 -device virtio-blk-device,drive=image \ 228 -drive if=none,id=image,file=$IMAGE,format=raw" 229 fi 230 GDB=gdb-multiarch 231 QEMU_NONDEBUG=-nographic 232 EFI=1 233 ;; 234 "zynq7") 235 QEMU_CMD="${QEMU_PATH}qemu-system-arm \ 236 -machine xilinx-zynq-a9 \ 237 -m 2G \ 238 -serial /dev/null \ 239 -serial mon:stdio" 240 GDB=gdb 241 QEMU_NONDEBUG=-nographic 242 ;; 243 *) 244 echo "No QEmu environment defined for architecture=$ARCH." >&2 245 exit 1 246 ;; 247esac 248 249export QEMU_AUDIO_DRV=none 250 251if test "$DEBUG_SCRIPT" = ""; then 252 echo "OK: about to run the follow qemu command:" 253 if test -z "$EFI"; then 254 if test -z "$IMAGE"; then 255 echo "$QEMU_CMD $QEMU_NONDEBUG -kernel $KERNEL -append '$KERNEL_CMDS' -initrd $INITRD" 256 exec $QEMU_CMD $QEMU_NONDEBUG -kernel $KERNEL -append '$KERNEL_CMDS' -initrd "$INITRD" 257 else 258 echo "$QEMU_CMD $QEMU_NONDEBUG -kernel $IMAGE" 259 exec $QEMU_CMD $QEMU_NONDEBUG -kernel "$IMAGE" 260 fi 261 else 262 echo $QEMU_CMD $QEMU_NONDEBUG 263 exec $QEMU_CMD $QEMU_NONDEBUG 264 fi 265fi 266 267 268# Now we run the debugger instead 269GDB_ARGS="-x $DEBUG_SCRIPT" 270SERIAL_OUTPUT=file:/dev/stdout 271PORT=$((10000 + UID)) 272 273if test "${SERIAL_OUTPUT}" = ""; then 274 # Assuming session is interactive. Use terminal for serial output because 275 # stdout does not work for daemonized qemu and output is lost. This likely 276 # only matters on ARM where there is no video driver at time of writing. 277 SERIAL_OUTPUT=`tty` 278fi 279 280PIDFILE=/tmp/qemu_debugsim_${USER}_${PORT}.pid 281if test -f $PIDFILE; then 282 if ps `cat $PIDFILE` >/dev/null; then 283 echo "Another QEMU already running (PID: `cat $PIDFILE` PIDFILE: $PIDFILE)" 284 exit 1 285 else 286 echo "Deleting stale lockfile $PIDFILE" 287 rm -f $PIDFILE 288 fi 289fi 290 291echo args = $GDB_ARGS 292 293cat > barrelfish_debug.gdb <<EOF 294# Connect to QEMU instance 295target remote localhost:$PORT 296EOF 297 298if test -z "$EFI"; then 299 if test -z "$IMAGE"; then 300 QEMU_INVOCATION="${QEMU_CMD} \ 301 -kernel \"$KERNEL\" \ 302 -append \"$KERNEL_CMDS\" \ 303 -initrd \"$INITRD\" \ 304 -serial $SERIAL_OUTPUT \ 305 -gdb tcp::$PORT \ 306 -S \ 307 -display none \ 308 -daemonize \ 309 -pidfile $PIDFILE" 310 else 311 QEMU_INVOCATION="${QEMU_CMD} \ 312 -kernel \"$IMAGE\" \ 313 -append \"$KERNEL_CMDS\" \ 314 -serial $SERIAL_OUTPUT \ 315 -gdb tcp::$PORT \ 316 -S \ 317 -display none \ 318 -daemonize \ 319 -pidfile $PIDFILE" 320 fi 321else 322 QEMU_INVOCATION="${QEMU_CMD} \ 323 -serial $SERIAL_OUTPUT \ 324 -gdb tcp::$PORT \ 325 -S \ 326 -display none \ 327 -daemonize \ 328 -pidfile $PIDFILE" 329fi 330 331echo $QEMU_INVOCATION 332set -x 333 334eval $QEMU_INVOCATION 335 336if test $? -eq 0; then 337 stty sane 338 trap '' INT 339 ${GDB} -x barrelfish_debug.gdb ${GDB_ARGS} 340 PID=`cat ${PIDFILE}` 341 kill ${PID} > /dev/null || true 342 rm -f $PIDFILE 343else 344 echo Failed to launch qemu with: 345 echo " ${QEMU_INVOCATION}" 346fi 347