blob: 0fb5bf611ffaf16b15260a7dbe707e1387b8b9fa [file] [edit]
#!/usr/bin/env bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
. "$DIR/qemu-shared.sh"
function HELP {
echo "help:"
echo "-p <project> : specify the project to build"
echo "-6 : 64bit"
echo "-S : supervisor mode (using OpenSBI, only works in 64bit)"
echo "-e : sifive e platform"
echo "-u : sifive u platform"
echo "-m <memory in MB> : memory size (default: 512 MB for virt, 8192 MB for sifive_u)"
echo "-s <number of cpus> : number of CPUs (default: 1, or 2 for sifive_u)"
echo "-X : print QEMU command and exit (dry run)"
echo
echo "-c : cmpctmalloc instead of dlmalloc"
echo "-M : miniheap instead of dlmalloc"
echo
echo "-A <cmd line> : append command line (may be used multiple times)"
echo "-d <disk image> : add a virtio block device (may be used multiple times)"
echo "-n : add a virtio network device (user mode networking)"
echo "-N <network driver> : specify network driver (requires -n or -t, e.g., virtio-net-device, virtio-net-pci)"
echo "-t : add a virtio tap network device (requires tap interface setup)"
echo "-g : add a virtio display (GPU, keyboard, mouse)"
echo "-C : PCI based virtio devices"
echo
echo "-h : show this help"
echo "all arguments after -- are passed to qemu directly"
exit 1
}
DO_NET=0
DO_NET_TAP=0
DISK_IMAGES=()
CMDLINE=""
DO_64BIT=0
DO_EMBEDDED=0
DO_UNLEASHED=0
DO_DISPLAY=0
DO_CMPCTMALLOC=0
DO_MINIHEAP=0
DO_SUPERVISOR=0
DO_PCI_VIRTIO=0
SMP=1
MEMSIZE=0
SUDO=""
PROJECT=""
DO_DRYRUN=0
NETDEV=""
DO_NETDEV_OVERRIDE=0
while getopts A:cCd:ghm:MntNeu6p:s:SX FLAG; do
case $FLAG in
A) CMDLINE+="${CMDLINE:+ }$(quote_cmdline_arg "$OPTARG")";;
c) DO_CMPCTMALLOC=1;;
C) DO_PCI_VIRTIO=1;;
d)
DISK_IMAGES+=("$OPTARG")
;;
g) DO_DISPLAY=1;;
M) DO_MINIHEAP=1;;
n) DO_NET=1;;
t) DO_NET_TAP=1;;
N) NETDEV=$OPTARG; DO_NETDEV_OVERRIDE=1;;
e) DO_EMBEDDED=1;;
u) DO_UNLEASHED=1;;
6) DO_64BIT=1;;
m) MEMSIZE=$OPTARG;;
s) SMP=$OPTARG;;
S) DO_SUPERVISOR=1;;
p) PROJECT=$OPTARG;;
X) DO_DRYRUN=1;;
h) HELP;;
\?)
echo unrecognized option
HELP
esac
done
shift $((OPTIND-1))
if (( DO_NET && DO_NET_TAP )); then
echo "Error: Cannot use both -n (user network) and -t (tap network) together"
exit 1
fi
if (( DO_NETDEV_OVERRIDE && ! ( DO_NET || DO_NET_TAP ) )); then
echo "Error: -N requires either -n (user network) or -t (tap network)"
exit 1
fi
CPU=""
BIOS=""
# Pick the appropriate qemu and project for each platform
# Also pick the default memory size and cpu count if not specified
if (( DO_UNLEASHED )); then
QEMU="qemu-system-riscv64"
MACHINE="sifive_u"
_PROJECT="qemu-sifive-u-test"
if (( $SMP == 1 )); then
SMP=2
fi
_MEMSIZE=8192
elif (( DO_EMBEDDED )); then
QEMU="qemu-system-riscv32"
MACHINE="sifive_e"
_PROJECT="sifive-e-test"
_MEMSIZE=0 # cant set memsize, it's fixed for this board (16K)
SMP=0
elif (( DO_64BIT )); then
QEMU="qemu-system-riscv64"
CPU="rv64"
MACHINE="virt"
_MEMSIZE=512
if (( DO_SUPERVISOR )); then
_PROJECT="qemu-virt-riscv64-supervisor-test"
BIOS="default"
else
_PROJECT="qemu-virt-riscv64-test"
BIOS="none"
fi
else
QEMU="qemu-system-riscv32"
CPU="rv32"
MACHINE="virt"
BIOS="none"
_MEMSIZE=512
_PROJECT="qemu-virt-riscv32-test"
fi
# command line PROJECT and MEMSIZE override defaults
if [[ -z "$PROJECT" ]]; then
PROJECT=$_PROJECT
fi
if [[ -z "$MEMSIZE" ]]; then
MEMSIZE=$_MEMSIZE
fi
if (( $DO_PCI_VIRTIO )); then
VIRTIO_BLOCK_DEVICE="virtio-blk-pci"
VIRTIO_NET_DEVICE="virtio-net-pci"
VIRTIO_GPU_DEVICE="virtio-gpu-pci"
VIRTIO_KEYBOARD_DEVICE="virtio-keyboard-pci"
VIRTIO_MOUSE_DEVICE="virtio-mouse-pci"
VIRTIO_9P_DEVICE="virtio-9p-pci"
VIRTIO_RNG_DEVICE="virtio-rng-pci"
else
VIRTIO_BLOCK_DEVICE="virtio-blk-device"
VIRTIO_NET_DEVICE="virtio-net-device"
VIRTIO_GPU_DEVICE="virtio-gpu-device"
VIRTIO_KEYBOARD_DEVICE="virtio-keyboard-device"
VIRTIO_MOUSE_DEVICE="virtio-mouse-device"
VIRTIO_9P_DEVICE="virtio-9p-device"
VIRTIO_RNG_DEVICE="virtio-rng-device"
fi
if (( ! DO_NETDEV_OVERRIDE )); then
NETDEV="$VIRTIO_NET_DEVICE"
fi
# construct a list of args based on previous variables using arrays
ARGS=()
ARGS+=("-machine" "$MACHINE")
# To dump the device tree for this config, use:
# ARGS=("-machine" "${MACHINE},dumpdtb=riscv.dtb")
ARGS+=("-kernel" "build-${PROJECT}/lk.elf")
if [[ -n "$CMDLINE" ]]; then
ARGS+=("-append" "$CMDLINE")
fi
if [[ -n "$CPU" ]]; then
ARGS+=("-cpu" "$CPU")
fi
if (( MEMSIZE )); then
ARGS+=("-m" "$MEMSIZE")
fi
if (( SMP )); then
ARGS+=("-smp" "$SMP")
fi
if [[ -n "$BIOS" ]]; then
ARGS+=("-bios" "$BIOS")
fi
DISK_COUNT=0
for img in "${DISK_IMAGES[@]}"; do
ARGS+=("-drive" "if=none,file=${img},id=disk${DISK_COUNT},format=raw")
ARGS+=("-device" "${VIRTIO_BLOCK_DEVICE},drive=disk${DISK_COUNT}")
((DISK_COUNT++))
done
if (( DO_NET )); then
ARGS+=("-netdev" "user,id=vmnic,hostname=qemu")
ARGS+=("-device" "${NETDEV},netdev=vmnic")
elif (( DO_NET_TAP )); then
# quick note to enable tap interface
# IFNAME=qemu0
# BRIDGE=bridge0
# sudo ip tuntap add name "${IFNAME}" mode tap user $(whoami)
# sudo ip link set "${IFNAME}" master "${BRIDGE}"
# sudo ip link set "${IFNAME}" up
ARGS+=("-netdev" "tap,id=vmnic,ifname=qemu0,script=no,downscript=no")
ARGS+=("-device" "${NETDEV},netdev=vmnic")
#SUDO="sudo"
else
ARGS+=("-net" "none")
fi
if (( DO_DISPLAY )); then
ARGS+=("-device" "${VIRTIO_GPU_DEVICE}")
ARGS+=("-serial" "stdio")
ARGS+=("-device" "${VIRTIO_KEYBOARD_DEVICE}")
ARGS+=("-device" "${VIRTIO_MOUSE_DEVICE}")
else
ARGS+=("-nographic")
fi
ARGS+=("-device" "${VIRTIO_RNG_DEVICE}")
MAKE_VARS=""
if (( DO_CMPCTMALLOC )); then
MAKE_VARS="LK_HEAP_IMPLEMENTATION=cmpctmalloc"
elif (( DO_MINIHEAP )); then
MAKE_VARS="LK_HEAP_IMPLEMENTATION=miniheap"
fi
CMD=()
if [[ -n "$SUDO" ]]; then
CMD+=("sudo")
fi
CMD+=("$QEMU")
CMD+=("${ARGS[@]}")
CMD+=("$@")
if (( DO_DRYRUN )); then
echo "${CMD[@]}"
exit 0
fi
"$DIR"/make-parallel $MAKE_VARS "$PROJECT" || exit 1
echo "${CMD[@]}" && exec "${CMD[@]}"