| #!/bin/bash -x |
| |
| # Handle running OE images under qemu |
| # |
| # Copyright (C) 2006-2011 Linux Foundation |
| # |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License version 2 as |
| # published by the Free Software Foundation. |
| # |
| # 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 General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License along |
| # with this program; if not, write to the Free Software Foundation, Inc., |
| # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| |
| # Call setting: |
| # QEMU_MEMORY (optional) - set the amount of memory in the emualted system. |
| # SERIAL_LOGFILE (optional) - log the serial port output to a file |
| # |
| # Image options: |
| # MACHINE - the machine to run |
| # FSTYPE - the image type to run |
| # KERNEL - the kernel image file to use |
| # ROOTFS - the disk image file to use |
| # |
| |
| mem_size=-1 |
| |
| #Get rid of <> and get the contents of extra qemu running params |
| SCRIPT_QEMU_EXTRA_OPT=`echo $SCRIPT_QEMU_EXTRA_OPT | sed -e 's/<//' -e 's/>//'` |
| #if user set qemu memory, eg: -m 256 in qemu extra params, we need to do some |
| # validation check |
| mem_set=`expr "$SCRIPT_QEMU_EXTRA_OPT" : '.*\(-m[[:space:]] *[0-9]*\)'` |
| if [ ! -z "$mem_set" ] ; then |
| #Get memory setting size from user input |
| mem_size=`echo $mem_set | sed 's/-m[[:space:]] *//'` |
| fi |
| |
| # This file is created when runqemu-gen-tapdevs creates a bank of tap |
| # devices, indicating that the user should not bring up new ones using |
| # sudo. |
| NOSUDO_FLAG="/etc/runqemu-nosudo" |
| |
| QEMUIFUP=`which runqemu-ifup 2> /dev/null` |
| QEMUIFDOWN=`which runqemu-ifdown 2> /dev/null` |
| if [ -z "$QEMUIFUP" -o ! -x "$QEMUIFUP" ]; then |
| echo "runqemu-ifup cannot be found or executed" |
| exit 1 |
| fi |
| if [ -z "$QEMUIFDOWN" -o ! -x "$QEMUIFDOWN" ]; then |
| echo "runqemu-ifdown cannot be found or executed" |
| exit 1 |
| fi |
| |
| NFSRUNNING="false" |
| |
| #capture original stty values |
| ORIG_STTY=$(stty -g) |
| |
| if [ "$SLIRP_ENABLED" = "yes" ]; then |
| KERNEL_NETWORK_CMD="ip=dhcp" |
| QEMU_TAP_CMD="" |
| QEMU_UI_OPTIONS="-show-cursor -usb -usbdevice tablet" |
| QEMU_NETWORK_CMD="" |
| DROOT="/dev/vda" |
| ROOTFS_OPTIONS="-drive file=$ROOTFS,if=virtio,format=raw" |
| else |
| acquire_lock() { |
| lockfile=$1 |
| if [ -z "$lockfile" ]; then |
| echo "Error: missing lockfile arg passed to acquire_lock()" |
| return 1 |
| fi |
| |
| touch $lockfile.lock 2>/dev/null |
| if [ $? -ne 0 ]; then |
| echo "Acquiring lockfile for $lockfile.lock failed" |
| return 1 |
| fi |
| exec 8>$lockfile.lock |
| flock -n -x 8 |
| if [ $? -ne 0 ]; then |
| exec 8>&- |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| release_lock() { |
| lockfile=$1 |
| if [ -z "$lockfile" ]; then |
| echo "Error: missing lockfile arg passed to release_lock()" |
| return 1 |
| fi |
| |
| rm -f $lockfile.lock |
| exec 8>&- |
| } |
| |
| LOCKDIR="/tmp/qemu-tap-locks" |
| if [ ! -d "$LOCKDIR" ]; then |
| mkdir $LOCKDIR |
| chmod 777 $LOCKDIR |
| fi |
| |
| IFCONFIG=`which ip 2> /dev/null` |
| if [ -z "$IFCONFIG" ]; then |
| IFCONFIG=/sbin/ip |
| fi |
| if [ ! -x "$IFCONFIG" ]; then |
| echo "$IFCONFIG cannot be executed" |
| exit 1 |
| fi |
| |
| POSSIBLE=`$IFCONFIG link | grep 'tap' | awk '{print $2}' | sed -e 's/://' -e 's/@.*//'` |
| TAP="" |
| LOCKFILE="" |
| USE_PRECONF_TAP="no" |
| for tap in $POSSIBLE; do |
| LOCKFILE="$LOCKDIR/$tap" |
| if [ -e "$LOCKFILE.skip" ]; then |
| echo "Found $LOCKFILE.skip, skipping $tap" |
| continue |
| fi |
| echo "Acquiring lockfile for $tap..." |
| acquire_lock $LOCKFILE |
| if [ $? -eq 0 ]; then |
| TAP=$tap |
| USE_PRECONF_TAP="yes" |
| break |
| fi |
| done |
| |
| if [ "$TAP" = "" ]; then |
| if [ -e "$NOSUDO_FLAG" ]; then |
| echo "Error: There are no available tap devices to use for networking," |
| echo "and I see $NOSUDO_FLAG exists, so I am not going to try creating" |
| echo "a new one with sudo." |
| exit 1 |
| fi |
| |
| GROUPID=`id -g` |
| USERID=`id -u` |
| echo "Setting up tap interface under sudo" |
| # Redirect stderr since we could see a LD_PRELOAD warning here if pseudo is loaded |
| # but inactive. This looks scary but is harmless |
| tap=`sudo $QEMUIFUP $USERID $GROUPID $OECORE_NATIVE_SYSROOT 2> /dev/null` |
| if [ $? -ne 0 ]; then |
| # Re-run standalone to see verbose errors |
| sudo $QEMUIFUP $USERID $GROUPID $OECORE_NATIVE_SYSROOT |
| return 1 |
| fi |
| LOCKFILE="$LOCKDIR/$tap" |
| echo "Acquiring lockfile for $tap..." |
| acquire_lock $LOCKFILE |
| if [ $? -eq 0 ]; then |
| TAP=$tap |
| fi |
| else |
| echo "Using preconfigured tap device '$TAP'" |
| echo "If this is not intended, touch $LOCKFILE.skip to make runqemu skip $TAP." |
| fi |
| |
| cleanup() { |
| if [ ! -e "$NOSUDO_FLAG" -a "$USE_PRECONF_TAP" = "no" ]; then |
| # Redirect stderr since we could see a LD_PRELOAD warning here if pseudo is loaded |
| # but inactive. This looks scary but is harmless |
| sudo $QEMUIFDOWN $TAP $OECORE_NATIVE_SYSROOT 2> /dev/null |
| fi |
| echo "Releasing lockfile of preconfigured tap device '$TAP'" |
| release_lock $LOCKFILE |
| |
| if [ "$NFSRUNNING" = "true" ]; then |
| echo "Shutting down the userspace NFS server..." |
| echo "runqemu-export-rootfs stop $ROOTFS" |
| runqemu-export-rootfs stop $ROOTFS |
| fi |
| # If QEMU crashes or somehow tty properties are not restored |
| # after qemu exits, we need to run stty sane |
| #stty sane |
| |
| #instead of using stty sane we set the original stty values |
| stty ${ORIG_STTY} |
| |
| } |
| |
| |
| n0=$(echo $TAP | sed 's/tap//') |
| |
| case $n0 in |
| ''|*[!0-9]*) |
| echo "Error Couldn't turn $TAP into an interface number?" |
| exit 1 |
| ;; |
| esac |
| |
| n1=$(($n0 * 2 + 1)) |
| n2=$(($n1 + 1)) |
| |
| KERNEL_NETWORK_CMD="ip=192.168.7.$n2::192.168.7.$n1:255.255.255.0" |
| QEMU_TAP_CMD="-net tap,vlan=0,ifname=$TAP,script=no,downscript=no" |
| if [ "$VHOST_ACTIVE" = "yes" ]; then |
| QEMU_NETWORK_CMD="-net nic,model=virtio $QEMU_TAP_CMD,vhost=on" |
| else |
| QEMU_NETWORK_CMD="-net nic,model=virtio $QEMU_TAP_CMD" |
| fi |
| DROOT="/dev/vda" |
| ROOTFS_OPTIONS="-drive file=$ROOTFS,if=virtio,format=raw" |
| |
| KERNCMDLINE="mem=$QEMU_MEMORY" |
| QEMU_UI_OPTIONS="-show-cursor -usb -usbdevice tablet" |
| |
| NFS_INSTANCE=`echo $TAP | sed 's/tap//'` |
| export NFS_INSTANCE |
| |
| SERIALOPTS="" |
| if [ "x$SERIAL_LOGFILE" != "x" ]; then |
| SERIALOPTS="-serial file:$SERIAL_LOGFILE" |
| fi |
| fi |
| |
| if [ ! -f "$KERNEL" -a "$IS_VM" = "false" ]; then |
| echo "Error: Kernel image file $KERNEL doesn't exist" |
| cleanup |
| return 1 |
| fi |
| |
| if [ "$FSTYPE" != "nfs" -a "$IS_VM" = "false" -a ! -f "$ROOTFS" ]; then |
| echo "Error: Image file $ROOTFS doesn't exist" |
| cleanup |
| return 1 |
| fi |
| |
| if [ "$NFS_SERVER" = "" ]; then |
| NFS_SERVER="192.168.7.1" |
| if [ "$SLIRP_ENABLED" = "yes" ]; then |
| NFS_SERVER="10.0.2.2" |
| fi |
| fi |
| |
| if [ "$FSTYPE" = "nfs" ]; then |
| NFS_DIR=`echo $ROOTFS | sed 's/^[^:]*:\(.*\)/\1/'` |
| if [ "$NFS_INSTANCE" = "" ] ; then |
| NFS_INSTANCE=0 |
| fi |
| MOUNTD_RPCPORT=$[ 21111 + $NFS_INSTANCE ] |
| NFSD_RPCPORT=$[ 11111 + $NFS_INSTANCE ] |
| NFSD_PORT=$[ 3049 + 2 * $NFS_INSTANCE ] |
| MOUNTD_PORT=$[ 3048 + 2 * $NFS_INSTANCE ] |
| UNFS_OPTS="nfsvers=3,port=$NFSD_PORT,mountprog=$MOUNTD_RPCPORT,nfsprog=$NFSD_RPCPORT,udp,mountport=$MOUNTD_PORT" |
| |
| PSEUDO_LOCALSTATEDIR=~/.runqemu-sdk/pseudo |
| export PSEUDO_LOCALSTATEDIR |
| |
| # Start the userspace NFS server |
| echo "runqemu-export-rootfs restart $ROOTFS" |
| runqemu-export-rootfs restart $ROOTFS |
| if [ $? != 0 ]; then |
| return 1 |
| fi |
| NFSRUNNING="true" |
| fi |
| |
| |
| set_mem_size() { |
| if [ ! -z "$mem_set" ] ; then |
| #Get memory setting size from user input |
| mem_size=`echo $mem_set | sed 's/-m[[:space:]] *//'` |
| else |
| mem_size=$1 |
| fi |
| # QEMU_MEMORY has 'M' appended to mem_size |
| QEMU_MEMORY="$mem_size"M |
| |
| } |
| |
| config_qemuarm() { |
| set_mem_size 128 |
| QEMU=qemu-system-arm |
| MACHINE_SUBTYPE=versatilepb |
| export QEMU_AUDIO_DRV="none" |
| QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS" |
| if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" -o "$FSTYPE" = "wic" ]; then |
| KERNCMDLINE="root=$DROOT rw console=ttyAMA0,115200 console=tty $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY highres=off" |
| QEMUOPTIONS="$QEMU_NETWORK_CMD -M ${MACHINE_SUBTYPE} $ROOTFS_OPTIONS -no-reboot $QEMU_UI_OPTIONS" |
| fi |
| if [ "$FSTYPE" = "nfs" ]; then |
| if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then |
| echo "Error: NFS mount point $ROOTFS doesn't exist" |
| cleanup |
| return 1 |
| fi |
| KERNCMDLINE="root=/dev/nfs nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw console=ttyAMA0,115200 $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" |
| QEMUOPTIONS="$QEMU_NETWORK_CMD -M ${MACHINE_SUBTYPE} --no-reboot $QEMU_UI_OPTIONS" |
| fi |
| if [ "$MACHINE" = "qemuarmv6" ]; then |
| QEMUOPTIONS="$QEMUOPTIONS -cpu arm1136" |
| fi |
| if [ "$MACHINE" = "qemuarmv7" ]; then |
| QEMUOPTIONS="$QEMUOPTIONS -cpu cortex-a8" |
| fi |
| } |
| |
| config_qemuarm64() { |
| set_mem_size 512 |
| QEMU=qemu-system-aarch64 |
| |
| QEMU_NETWORK_CMD="-netdev tap,id=net0,ifname=$TAP,script=no,downscript=no -device virtio-net-device,netdev=net0 " |
| DROOT="/dev/vda" |
| ROOTFS_OPTIONS="-drive id=disk0,file=$ROOTFS,if=none,format=raw -device virtio-blk-device,drive=disk0" |
| |
| export QEMU_AUDIO_DRV="none" |
| if [ "x$SERIALSTDIO" = "x" ] ; then |
| QEMU_UI_OPTIONS="-nographic" |
| else |
| QEMU_UI_OPTIONS="" |
| fi |
| if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" -o "$FSTYPE" = "wic" ]; then |
| KERNCMDLINE="root=$DROOT rw console=ttyAMA0,38400 mem=$QEMU_MEMORY highres=off $KERNEL_NETWORK_CMD" |
| # qemu-system-aarch64 only support '-machine virt -cpu cortex-a57' for now |
| QEMUOPTIONS="$QEMU_NETWORK_CMD -machine virt -cpu cortex-a57 $ROOTFS_OPTIONS $QEMU_UI_OPTIONS" |
| fi |
| if [ "$FSTYPE" = "nfs" ]; then |
| if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then |
| echo "Error: NFS mount point $ROOTFS doesn't exist" |
| cleanup |
| return 1 |
| fi |
| KERNCMDLINE="root=/dev/nfs nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw console=ttyAMA0,38400 mem=$QEMU_MEMORY highres=off $KERNEL_NETWORK_CMD" |
| QEMUOPTIONS="$QEMU_NETWORK_CMD -machine virt -cpu cortex-a57 $QEMU_UI_OPTIONS" |
| fi |
| } |
| |
| config_qemux86() { |
| set_mem_size 256 |
| QEMU=qemu-system-i386 |
| if [ "$KVM_ACTIVE" = "yes" ]; then |
| CPU_SUBTYPE=kvm32 |
| else |
| CPU_SUBTYPE=qemu32 |
| fi |
| if [ ! -z "$vga_option" ]; then |
| QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS" |
| else |
| QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS -vga vmware" |
| fi |
| if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" -o "$FSTYPE" = "wic" ]; then |
| KERNCMDLINE="vga=0 uvesafb.mode_option=640x480-32 root=$DROOT rw mem=$QEMU_MEMORY $KERNEL_NETWORK_CMD" |
| QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE $ROOTFS_OPTIONS $QEMU_UI_OPTIONS" |
| fi |
| if [ "${FSTYPE:0:4}" = "cpio" ]; then |
| KERNCMDLINE="vga=0 uvesafb.mode_option=640x480-32 root=/dev/ram0 rw mem=$QEMU_MEMORY $KERNEL_NETWORK_CMD" |
| QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE -initrd $ROOTFS $QEMU_UI_OPTIONS" |
| fi |
| |
| if [ "$FSTYPE" = "nfs" ]; then |
| if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then |
| echo "Error: NFS mount point $ROOTFS doesn't exist." |
| cleanup |
| return 1 |
| fi |
| KERNCMDLINE="root=/dev/nfs nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" |
| QEMUOPTIONS="$QEMU_NETWORK_CMD $QEMU_UI_OPTIONS" |
| fi |
| if [ "$IS_VM" = "true" ]; then |
| QEMUOPTIONS="$QEMU_NETWORK_CMD $QEMU_UI_OPTIONS" |
| fi |
| # Currently oprofile's event based interrupt mode doesn't work(Bug #828) in |
| # qemux86 and qemux86-64. We can use timer interrupt mode for now. |
| KERNCMDLINE="$KERNCMDLINE oprofile.timer=1" |
| } |
| |
| config_qemux86_64() { |
| set_mem_size 256 |
| QEMU=qemu-system-x86_64 |
| if [ "$KVM_ACTIVE" = "yes" ]; then |
| CPU_SUBTYPE=kvm64 |
| else |
| CPU_SUBTYPE=core2duo |
| fi |
| if [ ! -z "$vga_option" ]; then |
| QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS" |
| else |
| QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS -vga vmware" |
| fi |
| if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" -o "$FSTYPE" = "wic" ]; then |
| KERNCMDLINE="vga=0 uvesafb.mode_option=640x480-32 root=$DROOT rw mem=$QEMU_MEMORY $KERNEL_NETWORK_CMD" |
| QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE $ROOTFS_OPTIONS $QEMU_UI_OPTIONS" |
| fi |
| if [ "$FSTYPE" = "nfs" ]; then |
| if [ "x$ROOTFS" = "x" ]; then |
| ROOTFS=/srv/nfs/qemux86-64 |
| fi |
| if [ ! -d "$ROOTFS" ]; then |
| echo "Error: NFS mount point $ROOTFS doesn't exist." |
| cleanup |
| return 1 |
| fi |
| KERNCMDLINE="root=/dev/nfs nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" |
| QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE $QEMU_UI_OPTIONS" |
| fi |
| if [ "$IS_VM" = "true" ]; then |
| QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE $QEMU_UI_OPTIONS" |
| fi |
| # Currently oprofile's event based interrupt mode doesn't work(Bug #828) in |
| # qemux86 and qemux86-64. We can use timer interrupt mode for now. |
| KERNCMDLINE="$KERNCMDLINE oprofile.timer=1" |
| } |
| |
| config_qemumips() { |
| set_mem_size 256 |
| case "$MACHINE" in |
| qemumips) QEMU=qemu-system-mips ;; |
| qemumipsel) QEMU=qemu-system-mipsel ;; |
| qemumips64) QEMU=qemu-system-mips64 ;; |
| esac |
| MACHINE_SUBTYPE=malta |
| QEMU_UI_OPTIONS="-vga cirrus $QEMU_UI_OPTIONS" |
| if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" -o "$FSTYPE" = "wic" ]; then |
| #KERNCMDLINE="root=/dev/hda console=ttyS0 console=tty0 $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" |
| KERNCMDLINE="root=$DROOT rw console=ttyS0 console=tty $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" |
| QEMUOPTIONS="$QEMU_NETWORK_CMD -M $MACHINE_SUBTYPE $ROOTFS_OPTIONS -no-reboot $QEMU_UI_OPTIONS" |
| fi |
| if [ "$FSTYPE" = "nfs" ]; then |
| if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then |
| echo "Error: NFS mount point $ROOTFS doesn't exist" |
| cleanup |
| return 1 |
| fi |
| KERNCMDLINE="root=/dev/nfs console=ttyS0 console=tty nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" |
| QEMUOPTIONS="$QEMU_NETWORK_CMD -M $MACHINE_SUBTYPE -no-reboot $QEMU_UI_OPTIONS" |
| fi |
| } |
| |
| config_qemuppc() { |
| set_mem_size 256 |
| QEMU=qemu-system-ppc |
| MACHINE_SUBTYPE=mac99 |
| CPU_SUBTYPE=G4 |
| QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS" |
| if [ "$SLIRP_ENABLED" = "yes" ]; then |
| QEMU_NETWORK_CMD="" |
| else |
| QEMU_NETWORK_CMD="-net nic,model=pcnet $QEMU_TAP_CMD" |
| fi |
| if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" -o "$FSTYPE" = "wic" ]; then |
| KERNCMDLINE="root=$DROOT rw console=ttyS0 console=tty $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" |
| QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE -M $MACHINE_SUBTYPE $ROOTFS_OPTIONS -no-reboot $QEMU_UI_OPTIONS" |
| fi |
| if [ "$FSTYPE" = "nfs" ]; then |
| if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then |
| echo "Error: NFS mount point $ROOTFS doesn't exist" |
| cleanup |
| return 1 |
| fi |
| KERNCMDLINE="root=/dev/nfs console=ttyS0 console=tty nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" |
| QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE -M $MACHINE_SUBTYPE -no-reboot $QEMU_UI_OPTIONS" |
| fi |
| } |
| |
| config_qemush4() { |
| set_mem_size 1024 |
| QEMU=qemu-system-sh4 |
| MACHINE_SUBTYPE=r2d |
| QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS" |
| if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" -o "$FSTYPE" = "wic" ]; then |
| #KERNCMDLINE="root=/dev/hda console=ttyS0 console=tty0 $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" |
| KERNCMDLINE="root=/dev/hda rw console=ttySC1 noiotrap earlyprintk=sh-sci.1 console=tty $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" |
| QEMUOPTIONS="$QEMU_NETWORK_CMD -M $MACHINE_SUBTYPE -hda $ROOTFS -no-reboot $QEMU_UI_OPTIONS -monitor null -serial vc -serial stdio" |
| SERIALSTDIO="1" |
| fi |
| if [ "$FSTYPE" = "nfs" ]; then |
| if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then |
| echo "Error: NFS mount point $ROOTFS doesn't exist" |
| cleanup |
| return 1 |
| fi |
| KERNCMDLINE="root=/dev/nfs console=ttySC1 noiotrap earlyprintk=sh-sci.1 console=tty nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" |
| QEMUOPTIONS="$QEMU_NETWORK_CMD -M $MACHINE_SUBTYPE -no-reboot $QEMU_UI_OPTIONS -monitor null -serial vc -serial stdio" |
| SERIALSTDIO="1" |
| fi |
| } |
| |
| config_qemuzynq() { |
| set_mem_size 1024 |
| QEMU=qemu-system-arm |
| QEMU_SYSTEM_OPTIONS="$QEMU_NETWORK_CMD -M xilinx-zynq-a9 -serial null -serial mon:stdio -dtb $KERNEL-$MACHINE.dtb" |
| # zynq serial ports are named 'ttyPS0' and 'ttyPS1', fixup the default values |
| SCRIPT_KERNEL_OPT=$(echo "$SCRIPT_KERNEL_OPT" | sed 's/console=ttyS/console=ttyPS/g') |
| if [ "${FSTYPE:0:3}" = "ext" -o "${FSTYPE:0:4}" = "cpio" ]; then |
| KERNCMDLINE="earlyprintk root=/dev/ram rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" |
| QEMUOPTIONS="$QEMU_SYSTEM_OPTIONS -initrd $ROOTFS" |
| fi |
| } |
| |
| config_qemumicroblaze() { |
| set_mem_size 256 |
| QEMU=qemu-system-microblazeel |
| QEMU_SYSTEM_OPTIONS="$QEMU_NETWORK_CMD -M petalogix-ml605 -serial mon:stdio" |
| if [ "${FSTYPE:0:3}" = "ext" -o "${FSTYPE:0:4}" = "cpio" ]; then |
| KERNCMDLINE="earlyprintk root=/dev/ram rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY" |
| QEMUOPTIONS="$QEMU_SYSTEM_OPTIONS -initrd $ROOTFS" |
| fi |
| } |
| |
| case "$MACHINE" in |
| "qemuarm" | "qemuarmv6" | "qemuarmv7") |
| config_qemuarm |
| ;; |
| "qemuarm64") |
| config_qemuarm64 |
| ;; |
| "qemux86") |
| config_qemux86 |
| ;; |
| "qemux86-64") |
| config_qemux86_64 |
| ;; |
| "qemumips" | "qemumipsel" | "qemumips64") |
| config_qemumips |
| ;; |
| "qemuppc") |
| config_qemuppc |
| ;; |
| "qemush4") |
| config_qemush4 |
| ;; |
| "qemuzynq") |
| config_qemuzynq |
| ;; |
| "qemumicroblaze") |
| config_qemumicroblaze |
| ;; |
| *) |
| echo "Error: Unsupported machine type $MACHINE" |
| return 1 |
| ;; |
| esac |
| |
| # We need to specify -m <mem_size> to overcome a bug in qemu 0.14.0 |
| # https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/584480 |
| if [ -z "$mem_set" ] ; then |
| SCRIPT_QEMU_EXTRA_OPT="$SCRIPT_QEMU_EXTRA_OPT -m $mem_size" |
| fi |
| |
| if [ "${FSTYPE:0:3}" = "ext" ]; then |
| KERNCMDLINE="$KERNCMDLINE rootfstype=$FSTYPE" |
| fi |
| |
| if [ "$FSTYPE" = "cpio.gz" ]; then |
| QEMUOPTIONS="-initrd $ROOTFS -nographic" |
| KERNCMDLINE="root=/dev/ram0 console=ttyS0 debugshell" |
| fi |
| |
| if [ "$FSTYPE" = "iso" ]; then |
| QEMUOPTIONS="$QEMU_NETWORK_CMD -cdrom $ROOTFS $QEMU_UI_OPTIONS" |
| fi |
| |
| if [ "x$QEMUOPTIONS" = "x" ]; then |
| echo "Error: Unable to support this combination of options" |
| cleanup |
| return 1 |
| fi |
| |
| if [ "$TCPSERIAL_PORTNUM" != "" ]; then |
| if [ "$MACHINE" = "qemuarm64" ]; then |
| SCRIPT_QEMU_EXTRA_OPT="$SCRIPT_QEMU_EXTRA_OPT -device virtio-serial-device -chardev socket,id=virtcon,port=$TCPSERIAL_PORTNUM,host=127.0.0.1 -device virtconsole,chardev=virtcon" |
| else |
| SCRIPT_QEMU_EXTRA_OPT="$SCRIPT_QEMU_EXTRA_OPT -serial tcp:127.0.0.1:$TCPSERIAL_PORTNUM" |
| fi |
| fi |
| |
| PATH=$OECORE_NATIVE_SYSROOT/usr/bin:$PATH |
| |
| QEMUBIN=`which $QEMU 2> /dev/null` |
| if [ ! -x "$QEMUBIN" ]; then |
| echo "Error: No QEMU binary '$QEMU' could be found." |
| cleanup |
| return 1 |
| fi |
| |
| NEED_GL=`ldd $QEMUBIN/$QEMU 2>&1 | grep libGLU` |
| # We can't run without a libGL.so |
| if [ "$NEED_GL" != "" ]; then |
| libgl='no' |
| |
| [ -e /usr/lib/libGL.so -a -e /usr/lib/libGLU.so ] && libgl='yes' |
| [ -e /usr/lib64/libGL.so -a -e /usr/lib64/libGLU.so ] && libgl='yes' |
| [ -e /usr/lib/*-linux-gnu/libGL.so -a -e /usr/lib/*-linux-gnu/libGLU.so ] && libgl='yes' |
| |
| if [ "$libgl" != 'yes' ]; then |
| echo "You need libGL.so and libGLU.so to exist in your library path to run the QEMU emulator. |
| Ubuntu package names are: libgl1-mesa-dev and libglu1-mesa-dev. |
| Fedora package names are: mesa-libGL-devel mesa-libGLU-devel." |
| return 1; |
| fi |
| fi |
| |
| do_quit() { |
| cleanup |
| return 1 |
| } |
| |
| trap do_quit INT TERM QUIT |
| |
| # qemu got segfault if linked with nVidia's libgl |
| GL_LD_PRELOAD=$LD_PRELOAD |
| |
| if ldd $QEMUBIN | grep -i nvidia &> /dev/null |
| then |
| cat << EOM |
| WARNING: nVidia proprietary OpenGL libraries detected. |
| nVidia's OpenGL libraries are known to have compatibility issues with qemu, |
| resulting in a segfault. Please uninstall these drivers or ensure the mesa libGL |
| libraries precede nvidia's via LD_PRELOAD(Already do it on Ubuntu 10). |
| EOM |
| |
| # Automatically use Ubuntu system's mesa libGL, other distro can add its own path |
| if grep -i ubuntu /etc/lsb-release &> /dev/null |
| then |
| # precede nvidia's driver on Ubuntu 10 |
| UBUNTU_MAIN_VERSION=`cat /etc/lsb-release |grep DISTRIB_RELEASE |cut -d= -f 2| cut -d. -f 1` |
| if [ "$UBUNTU_MAIN_VERSION" = "10" ]; |
| then |
| GL_PATH="" |
| if test -e /usr/lib/libGL.so |
| then |
| GL_PATH="/usr/lib/libGL.so" |
| elif test -e /usr/lib/x86_64-linux-gnu/libGL.so |
| then |
| GL_PATH="/usr/lib/x86_64-linux-gnu/libGL.so" |
| fi |
| |
| echo "Skip nVidia's libGL on Ubuntu 10!" |
| GL_LD_PRELOAD="$GL_PATH $LD_PRELOAD" |
| fi |
| fi |
| fi |
| |
| if [ "x$SERIALSTDIO" = "x1" ]; then |
| echo "Interrupt character is '^]'" |
| stty intr ^] |
| fi |
| |
| |
| # Preserve the multiplexing behavior for the monitor that would be there based |
| # on whether nographic is used. |
| if echo "$QEMUOPTIONS $SERIALOPTS $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT" | grep -- "-nographic"; then |
| FIRST_SERIAL_OPT="-serial mon:stdio" |
| else |
| FIRST_SERIAL_OPT="-serial mon:vc" |
| fi |
| |
| # qemuarm64 uses virtio for any additional serial ports so the normal mechanism |
| # of using -serial will not work |
| if [ "$MACHINE" = "qemuarm64" ]; then |
| SECOND_SERIAL_OPT="$SCRIPT_QEMU_EXTRA_OPT -device virtio-serial-device -chardev null,id=virtcon -device virtconsole,chardev=virtcon" |
| else |
| SECOND_SERIAL_OPT="-serial null" |
| fi |
| |
| # We always want a ttyS1. Since qemu by default adds a serial port when |
| # nodefaults is not specified, it seems that all that would be needed is to |
| # make sure a "-serial" is there. However, it appears that when "-serial" is |
| # specified, it ignores the default serial port that is normally added. |
| # So here we make sure to add two -serial if there are none. And only one |
| # if there is one -serial already. |
| NUM_SERIAL_OPTS=`echo $QEMUOPTIONS $SERIALOPTS $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT | sed -e 's/ /\n/g' | grep --count -- -serial` |
| |
| if [ "$NUM_SERIAL_OPTS" = "0" ]; then |
| SCRIPT_QEMU_EXTRA_OPT="$SCRIPT_QEMU_EXTRA_OPT $FIRST_SERIAL_OPT $SECOND_SERIAL_OPT" |
| elif [ "$NUM_SERIAL_OPTS" = "1" ]; then |
| SCRIPT_QEMU_EXTRA_OPT="$SCRIPT_QEMU_EXTRA_OPT $SECOND_SERIAL_OPT" |
| fi |
| |
| echo "Running $QEMU..." |
| # -no-reboot is a mandatory option - see bug #100 |
| if [ "$IS_VM" = "true" ]; then |
| # Check root=/dev/sdX or root=/dev/vdX |
| [ ! -e "$VM" ] && error "VM image is not found!" |
| if grep -q 'root=/dev/sd' $VM; then |
| echo "Using scsi drive" |
| VM_DRIVE="-drive if=none,id=hd,file=$VM -device virtio-scsi-pci,id=scsi -device scsi-hd,drive=hd" |
| elif grep -q 'root=/dev/hd' $VM; then |
| echo "Using ide drive" |
| VM_DRIVE="$VM" |
| else |
| echo "Using virtio block drive" |
| VM_DRIVE="-drive if=virtio,file=$VM" |
| fi |
| QEMU_FIRE="$QEMUBIN $VM_DRIVE $QEMUOPTIONS $SERIALOPTS -no-reboot $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT" |
| echo $QEMU_FIRE |
| LD_PRELOAD="$GL_LD_PRELOAD" $QEMU_FIRE |
| elif [ "$FSTYPE" = "iso" -o "$FSTYPE" = "wic" ]; then |
| QEMU_FIRE="$QEMUBIN $QEMUOPTIONS $SERIALOPTS -no-reboot $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT" |
| echo $QEMU_FIRE |
| LD_PRELOAD="$GL_LD_PRELOAD" $QEMU_FIRE |
| else |
| QEMU_FIRE="$QEMUBIN -kernel $KERNEL $QEMUOPTIONS $SLIRP_CMD $SERIALOPTS -no-reboot $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT" |
| echo $QEMU_FIRE -append '"'$KERNCMDLINE $SCRIPT_KERNEL_OPT'"' |
| LD_PRELOAD="$GL_LD_PRELOAD" $QEMU_FIRE -append "$KERNCMDLINE $SCRIPT_KERNEL_OPT" |
| fi |
| ret=$? |
| if [ "$SLIRP_ENABLED" != "yes" ]; then |
| cleanup |
| fi |
| |
| #set the original stty values before exit |
| stty ${ORIG_STTY} |
| trap - INT TERM QUIT |
| |
| return $ret |