diff --git a/Config.in b/Config.in index fa019d5f..1bc04ea9 100644 --- a/Config.in +++ b/Config.in @@ -3,3 +3,10 @@ menu "Packages" source "$BR2_EXTERNAL_INFIX_PATH/package/Config.in" endmenu + +menu "QEMU Virtualization" + +source "$BR2_EXTERNAL_INFIX_PATH/qemu/Config.in" + +endmenu + diff --git a/Makefile b/Makefile index 98c472a2..06001c2f 100644 --- a/Makefile +++ b/Makefile @@ -18,14 +18,11 @@ $(config): @echo "'make _defconfig' before building an image." @exit 1 + %: | buildroot/Makefile @+$(call bmake,$@) buildroot/Makefile: @git submodule update --init -run: - @echo "Starting Qemu :: Ctrl-a x -- exit | Ctrl-a c -- toggle console/monitor" - @(cd $(O)/images && ./qemu.sh) - -.PHONY: all run +.PHONY: all diff --git a/external.mk b/external.mk index 214901ca..1243eea8 100644 --- a/external.mk +++ b/external.mk @@ -1 +1,6 @@ include $(sort $(wildcard $(BR2_EXTERNAL_INFIX_PATH)/package/*/*.mk)) + +.PHONY: run +run: + @echo "Starting Qemu :: Ctrl-a x -- exit | Ctrl-a c -- toggle console/monitor" + @$(BR2_EXTERNAL_INFIX_PATH)/qemu/qemu.sh $O diff --git a/qemu/Config.in b/qemu/Config.in new file mode 100644 index 00000000..31d02313 --- /dev/null +++ b/qemu/Config.in @@ -0,0 +1,68 @@ +config QEMU_MACHINE + string + default "qemu-system-aarch64 -M virt -cpu cortex-a72" if BR2_aarch64 + +config QEMU_KERNEL + string + default "images/Image" if BR2_aarch64 + +config QEMU_ROOTFS + string + default "images/rootfs.squashfs" + +config QEMU_RW + string "Writable layer" + default "images/rw.ext4" + +config QEMU_CONSOLE + string + default "ttyAMA0" if BR2_aarch64 + +choice + prompt "Rootfs type" + default QEMU_ROOTFS_INITRD + +config QEMU_ROOTFS_INITRD + bool "Initrd" + +config QEMU_ROOTFS_VSCSI + bool "Virtio SCSI" + +endchoice + +choice + prompt "Networking" + default QEMU_NET_USER + +config QEMU_NET_NONE + bool "None" + +config QEMU_NET_BRIDGE + bool "Bridged" + +config QEMU_NET_USER + bool "User mode" + +config QEMU_NET_TAP + bool "TAP" + +endchoice + +config QEMU_NET_MODEL + string "Interface model" + default "virtio" + +config QEMU_NET_BRIDGE_DEV + string "Bridge device" + depends on QEMU_NET_BRIDGE + default "virbr0" + +config QEMU_NET_TAP_N + int "Number of TAPs" + depends on QEMU_NET_TAP + default 1 + +config QEMU_APPEND + string "Extra kernel options" +config QEMU_EXTRA + string "Extra QEMU options" diff --git a/qemu/qemu.sh b/qemu/qemu.sh new file mode 100755 index 00000000..73fc95fc --- /dev/null +++ b/qemu/qemu.sh @@ -0,0 +1,101 @@ +#!/bin/sh + +die() +{ + echo "$@" >&2 + exit 1 +} + +load_qemucfg() +{ + local tmp=$(mktemp -p /tmp) + + grep ^QEMU_ $1 >$tmp + . $tmp + rm $tmp + + [ "$QEMU_MACHINE" ] || die "Missing QEMU_MACHINE" + [ "$QEMU_KERNEL" ] || die "Missing QEMU_KERNEL" + [ "$QEMU_ROOTFS" ] || die "Missing QEMU_ROOTFS" + [ "$QEMU_CONSOLE" ] || die "Missing QEMU_CONSOLE" +} + +append_args() +{ + echo -n "console=$QEMU_CONSOLE " + + if [ "$QEMU_ROOTFS_INITRD" = "y" ]; then + # Size of initrd, rounded up to nearest kb + local size=$((($(stat -c %s $QEMU_ROOTFS) + 1023) >> 10)) + echo -n "root=/dev/ram ramdisk_size=${size} " + elif [ "$QEMU_ROOTFS_VSCSI" = "y" ]; then + echo -n "root=/dev/vda " + fi + + if [ "$V" != "1" ]; then + echo -n "quiet " + else + echo -n "debug " + fi + + echo -n "${QEMU_APPEND} " +} + +rootfs_args() +{ + if [ "$QEMU_ROOTFS_INITRD" = "y" ]; then + echo -n "-initrd $QEMU_ROOTFS " + elif [ "$QEMU_ROOTFS_VSCSI" = "y" ]; then + echo -n "-drive file=$QEMU_ROOTFS,if=virtio,format=raw,bus=0,unit=0 " + fi +} + +rw_args() +{ + [ "$QEMU_RW" ] || return + + if ! [ -f $QEMU_RW ]; then + echo Creating $QEMU_RW + dd if=/dev/zero of=$QEMU_RW bs=16M count=1 + mkfs.ext4 -L infix-rw $QEMU_RW + fi + + echo -n "-drive file=$QEMU_RW,if=virtio,format=raw,bus=0,unit=1 " +} + +net_args() +{ + QEMU_NET_MODEL=${QEMU_NET_MODEL:-virtio} + + if [ "$QEMU_NET_BRIDGE" = "y" ]; then + QEMU_NET_BRIDGE_DEV=${QEMU_NET_BRIDGE_DEV:-virbr0} + echo -n "-nic bridge,br=$QEMU_NET_BRIDGE_DEV,model=$QEMU_NET_MODEL " + elif [ "$QEMU_NET_TAP" = "y" ]; then + QEMU_NET_TAP_N=${QEMU_NET_TAP_N:-1} + for i in $(seq 0 $(($QEMU_NET_TAP_N - 1))); do + echo -n "-nic tap,ifname=qtap$i,script=no,model=$QEMU_NET_MODEL " + done + elif [ "$QEMU_NET_USER" = "y" ]; then + echo -n "-nic user,model=$QEMU_NET_MODEL " + else + echo -n "-nic none" + fi +} + +if [ "$1" ]; then + [ -d "$1" ] || die "Usage: qemu.sh " + cd $1 +fi + +load_qemucfg .config + +$QEMU_MACHINE -nographic \ + -kernel $QEMU_KERNEL \ + $(rootfs_args) \ + $(rw_args) \ + $(net_args) \ + -append "$(append_args)" \ + $QEMU_EXTRA + + +