blob: ac1c703c53732fd12a95b4ef80c44d8613f63ddd [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#!/bin/bash -x
2
3# Handle running OE images under qemu
4#
5# Copyright (C) 2006-2011 Linux Foundation
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License version 2 as
9# published by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program; if not, write to the Free Software Foundation, Inc.,
18# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20# Call setting:
21# QEMU_MEMORY (optional) - set the amount of memory in the emualted system.
22# SERIAL_LOGFILE (optional) - log the serial port output to a file
23#
24# Image options:
25# MACHINE - the machine to run
26# FSTYPE - the image type to run
27# KERNEL - the kernel image file to use
28# ROOTFS - the disk image file to use
29#
30
Patrick Williamsc124f4f2015-09-15 14:41:29 -050031mem_size=-1
32
33#Get rid of <> and get the contents of extra qemu running params
34SCRIPT_QEMU_EXTRA_OPT=`echo $SCRIPT_QEMU_EXTRA_OPT | sed -e 's/<//' -e 's/>//'`
35#if user set qemu memory, eg: -m 256 in qemu extra params, we need to do some
36# validation check
37mem_set=`expr "$SCRIPT_QEMU_EXTRA_OPT" : '.*\(-m[[:space:]] *[0-9]*\)'`
38if [ ! -z "$mem_set" ] ; then
39#Get memory setting size from user input
40 mem_size=`echo $mem_set | sed 's/-m[[:space:]] *//'`
Patrick Williamsc124f4f2015-09-15 14:41:29 -050041fi
42
Patrick Williamsc124f4f2015-09-15 14:41:29 -050043# This file is created when runqemu-gen-tapdevs creates a bank of tap
44# devices, indicating that the user should not bring up new ones using
45# sudo.
46NOSUDO_FLAG="/etc/runqemu-nosudo"
47
48QEMUIFUP=`which runqemu-ifup 2> /dev/null`
49QEMUIFDOWN=`which runqemu-ifdown 2> /dev/null`
50if [ -z "$QEMUIFUP" -o ! -x "$QEMUIFUP" ]; then
51 echo "runqemu-ifup cannot be found or executed"
52 exit 1
53fi
54if [ -z "$QEMUIFDOWN" -o ! -x "$QEMUIFDOWN" ]; then
55 echo "runqemu-ifdown cannot be found or executed"
56 exit 1
57fi
58
59NFSRUNNING="false"
60
61#capture original stty values
62ORIG_STTY=$(stty -g)
63
64if [ "$SLIRP_ENABLED" = "yes" ]; then
65 KERNEL_NETWORK_CMD="ip=dhcp"
66 QEMU_TAP_CMD=""
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050067 QEMU_UI_OPTIONS="-show-cursor -usb -usbdevice tablet"
Patrick Williamsf1e5d692016-03-30 15:21:19 -050068 QEMU_NETWORK_CMD=""
69 DROOT="/dev/vda"
70 ROOTFS_OPTIONS="-drive file=$ROOTFS,if=virtio,format=raw"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050071else
72 acquire_lock() {
73 lockfile=$1
74 if [ -z "$lockfile" ]; then
75 echo "Error: missing lockfile arg passed to acquire_lock()"
76 return 1
77 fi
78
79 touch $lockfile.lock 2>/dev/null
80 if [ $? -ne 0 ]; then
81 echo "Acquiring lockfile for $lockfile.lock failed"
82 return 1
83 fi
84 exec 8>$lockfile.lock
85 flock -n -x 8
86 if [ $? -ne 0 ]; then
87 exec 8>&-
88 return 1
89 fi
90
91 return 0
92 }
93
94 release_lock() {
95 lockfile=$1
96 if [ -z "$lockfile" ]; then
97 echo "Error: missing lockfile arg passed to release_lock()"
98 return 1
99 fi
100
101 rm -f $lockfile.lock
102 exec 8>&-
103 }
104
105 LOCKDIR="/tmp/qemu-tap-locks"
106 if [ ! -d "$LOCKDIR" ]; then
107 mkdir $LOCKDIR
108 chmod 777 $LOCKDIR
109 fi
110
111 IFCONFIG=`which ip 2> /dev/null`
112 if [ -z "$IFCONFIG" ]; then
113 IFCONFIG=/sbin/ip
114 fi
115 if [ ! -x "$IFCONFIG" ]; then
116 echo "$IFCONFIG cannot be executed"
117 exit 1
118 fi
119
120 POSSIBLE=`$IFCONFIG link | grep 'tap' | awk '{print $2}' | sed -e 's/://' -e 's/@.*//'`
121 TAP=""
122 LOCKFILE=""
123 USE_PRECONF_TAP="no"
124 for tap in $POSSIBLE; do
125 LOCKFILE="$LOCKDIR/$tap"
126 if [ -e "$LOCKFILE.skip" ]; then
127 echo "Found $LOCKFILE.skip, skipping $tap"
128 continue
129 fi
130 echo "Acquiring lockfile for $tap..."
131 acquire_lock $LOCKFILE
132 if [ $? -eq 0 ]; then
133 TAP=$tap
134 USE_PRECONF_TAP="yes"
135 break
136 fi
137 done
138
139 if [ "$TAP" = "" ]; then
140 if [ -e "$NOSUDO_FLAG" ]; then
141 echo "Error: There are no available tap devices to use for networking,"
142 echo "and I see $NOSUDO_FLAG exists, so I am not going to try creating"
143 echo "a new one with sudo."
144 exit 1
145 fi
146
147 GROUPID=`id -g`
148 USERID=`id -u`
149 echo "Setting up tap interface under sudo"
150 # Redirect stderr since we could see a LD_PRELOAD warning here if pseudo is loaded
151 # but inactive. This looks scary but is harmless
152 tap=`sudo $QEMUIFUP $USERID $GROUPID $OECORE_NATIVE_SYSROOT 2> /dev/null`
153 if [ $? -ne 0 ]; then
154 # Re-run standalone to see verbose errors
155 sudo $QEMUIFUP $USERID $GROUPID $OECORE_NATIVE_SYSROOT
156 return 1
157 fi
158 LOCKFILE="$LOCKDIR/$tap"
159 echo "Acquiring lockfile for $tap..."
160 acquire_lock $LOCKFILE
161 if [ $? -eq 0 ]; then
162 TAP=$tap
163 fi
164 else
165 echo "Using preconfigured tap device '$TAP'"
166 echo "If this is not intended, touch $LOCKFILE.skip to make runqemu skip $TAP."
167 fi
168
169 cleanup() {
170 if [ ! -e "$NOSUDO_FLAG" -a "$USE_PRECONF_TAP" = "no" ]; then
171 # Redirect stderr since we could see a LD_PRELOAD warning here if pseudo is loaded
172 # but inactive. This looks scary but is harmless
173 sudo $QEMUIFDOWN $TAP $OECORE_NATIVE_SYSROOT 2> /dev/null
174 fi
175 echo "Releasing lockfile of preconfigured tap device '$TAP'"
176 release_lock $LOCKFILE
177
178 if [ "$NFSRUNNING" = "true" ]; then
179 echo "Shutting down the userspace NFS server..."
180 echo "runqemu-export-rootfs stop $ROOTFS"
181 runqemu-export-rootfs stop $ROOTFS
182 fi
183 # If QEMU crashes or somehow tty properties are not restored
184 # after qemu exits, we need to run stty sane
185 #stty sane
186
187 #instead of using stty sane we set the original stty values
188 stty ${ORIG_STTY}
189
190 }
191
192
193 n0=$(echo $TAP | sed 's/tap//')
194
195 case $n0 in
196 ''|*[!0-9]*)
197 echo "Error Couldn't turn $TAP into an interface number?"
198 exit 1
199 ;;
200 esac
201
202 n1=$(($n0 * 2 + 1))
203 n2=$(($n1 + 1))
204
205 KERNEL_NETWORK_CMD="ip=192.168.7.$n2::192.168.7.$n1:255.255.255.0"
206 QEMU_TAP_CMD="-net tap,vlan=0,ifname=$TAP,script=no,downscript=no"
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500207 if [ "$VHOST_ACTIVE" = "yes" ]; then
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500208 QEMU_NETWORK_CMD="-net nic,model=virtio $QEMU_TAP_CMD,vhost=on"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500209 else
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500210 QEMU_NETWORK_CMD="-net nic,model=virtio $QEMU_TAP_CMD"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500211 fi
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500212 DROOT="/dev/vda"
213 ROOTFS_OPTIONS="-drive file=$ROOTFS,if=virtio,format=raw"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500214
215 KERNCMDLINE="mem=$QEMU_MEMORY"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500216 QEMU_UI_OPTIONS="-show-cursor -usb -usbdevice tablet"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500217
218 NFS_INSTANCE=`echo $TAP | sed 's/tap//'`
219 export NFS_INSTANCE
220
221 SERIALOPTS=""
222 if [ "x$SERIAL_LOGFILE" != "x" ]; then
223 SERIALOPTS="-serial file:$SERIAL_LOGFILE"
224 fi
225fi
226
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500227if [ ! -f "$KERNEL" -a "$IS_VM" = "false" ]; then
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500228 echo "Error: Kernel image file $KERNEL doesn't exist"
229 cleanup
230 return 1
231fi
232
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500233if [ "$FSTYPE" != "nfs" -a "$IS_VM" = "false" -a ! -f "$ROOTFS" ]; then
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500234 echo "Error: Image file $ROOTFS doesn't exist"
235 cleanup
236 return 1
237fi
238
239if [ "$NFS_SERVER" = "" ]; then
240 NFS_SERVER="192.168.7.1"
241 if [ "$SLIRP_ENABLED" = "yes" ]; then
242 NFS_SERVER="10.0.2.2"
243 fi
244fi
245
246if [ "$FSTYPE" = "nfs" ]; then
247 NFS_DIR=`echo $ROOTFS | sed 's/^[^:]*:\(.*\)/\1/'`
248 if [ "$NFS_INSTANCE" = "" ] ; then
249 NFS_INSTANCE=0
250 fi
251 MOUNTD_RPCPORT=$[ 21111 + $NFS_INSTANCE ]
252 NFSD_RPCPORT=$[ 11111 + $NFS_INSTANCE ]
253 NFSD_PORT=$[ 3049 + 2 * $NFS_INSTANCE ]
254 MOUNTD_PORT=$[ 3048 + 2 * $NFS_INSTANCE ]
255 UNFS_OPTS="nfsvers=3,port=$NFSD_PORT,mountprog=$MOUNTD_RPCPORT,nfsprog=$NFSD_RPCPORT,udp,mountport=$MOUNTD_PORT"
256
257 PSEUDO_LOCALSTATEDIR=~/.runqemu-sdk/pseudo
258 export PSEUDO_LOCALSTATEDIR
259
260 # Start the userspace NFS server
261 echo "runqemu-export-rootfs restart $ROOTFS"
262 runqemu-export-rootfs restart $ROOTFS
263 if [ $? != 0 ]; then
264 return 1
265 fi
266 NFSRUNNING="true"
267fi
268
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500269
270set_mem_size() {
271 if [ ! -z "$mem_set" ] ; then
272 #Get memory setting size from user input
273 mem_size=`echo $mem_set | sed 's/-m[[:space:]] *//'`
274 else
275 mem_size=$1
276 fi
277 # QEMU_MEMORY has 'M' appended to mem_size
278 QEMU_MEMORY="$mem_size"M
279
280}
281
282config_qemuarm() {
283 set_mem_size 128
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500284 QEMU=qemu-system-arm
285 MACHINE_SUBTYPE=versatilepb
286 export QEMU_AUDIO_DRV="none"
287 QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500288 if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" -o "$FSTYPE" = "wic" ]; then
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500289 KERNCMDLINE="root=$DROOT rw console=ttyAMA0,115200 console=tty $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY highres=off"
290 QEMUOPTIONS="$QEMU_NETWORK_CMD -M ${MACHINE_SUBTYPE} $ROOTFS_OPTIONS -no-reboot $QEMU_UI_OPTIONS"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500291 fi
292 if [ "$FSTYPE" = "nfs" ]; then
293 if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then
294 echo "Error: NFS mount point $ROOTFS doesn't exist"
295 cleanup
296 return 1
297 fi
298 KERNCMDLINE="root=/dev/nfs nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw console=ttyAMA0,115200 $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
299 QEMUOPTIONS="$QEMU_NETWORK_CMD -M ${MACHINE_SUBTYPE} --no-reboot $QEMU_UI_OPTIONS"
300 fi
301 if [ "$MACHINE" = "qemuarmv6" ]; then
302 QEMUOPTIONS="$QEMUOPTIONS -cpu arm1136"
303 fi
304 if [ "$MACHINE" = "qemuarmv7" ]; then
305 QEMUOPTIONS="$QEMUOPTIONS -cpu cortex-a8"
306 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500307}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500308
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500309config_qemuarm64() {
310 set_mem_size 512
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500311 QEMU=qemu-system-aarch64
312
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500313 QEMU_NETWORK_CMD="-netdev tap,id=net0,ifname=$TAP,script=no,downscript=no -device virtio-net-device,netdev=net0 "
314 DROOT="/dev/vda"
315 ROOTFS_OPTIONS="-drive id=disk0,file=$ROOTFS,if=none,format=raw -device virtio-blk-device,drive=disk0"
316
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500317 export QEMU_AUDIO_DRV="none"
318 if [ "x$SERIALSTDIO" = "x" ] ; then
319 QEMU_UI_OPTIONS="-nographic"
320 else
321 QEMU_UI_OPTIONS=""
322 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500323 if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" -o "$FSTYPE" = "wic" ]; then
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500324 KERNCMDLINE="root=$DROOT rw console=ttyAMA0,38400 mem=$QEMU_MEMORY highres=off $KERNEL_NETWORK_CMD"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500325 # qemu-system-aarch64 only support '-machine virt -cpu cortex-a57' for now
326 QEMUOPTIONS="$QEMU_NETWORK_CMD -machine virt -cpu cortex-a57 $ROOTFS_OPTIONS $QEMU_UI_OPTIONS"
327 fi
328 if [ "$FSTYPE" = "nfs" ]; then
329 if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then
330 echo "Error: NFS mount point $ROOTFS doesn't exist"
331 cleanup
332 return 1
333 fi
334 KERNCMDLINE="root=/dev/nfs nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw console=ttyAMA0,38400 mem=$QEMU_MEMORY highres=off $KERNEL_NETWORK_CMD"
335 QEMUOPTIONS="$QEMU_NETWORK_CMD -machine virt -cpu cortex-a57 $QEMU_UI_OPTIONS"
336 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500337}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500338
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500339config_qemux86() {
340 set_mem_size 256
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500341 QEMU=qemu-system-i386
342 if [ "$KVM_ACTIVE" = "yes" ]; then
343 CPU_SUBTYPE=kvm32
344 else
345 CPU_SUBTYPE=qemu32
346 fi
347 if [ ! -z "$vga_option" ]; then
348 QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS"
349 else
350 QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS -vga vmware"
351 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500352 if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" -o "$FSTYPE" = "wic" ]; then
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500353 KERNCMDLINE="vga=0 uvesafb.mode_option=640x480-32 root=$DROOT rw mem=$QEMU_MEMORY $KERNEL_NETWORK_CMD"
354 QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE $ROOTFS_OPTIONS $QEMU_UI_OPTIONS"
355 fi
356 if [ "${FSTYPE:0:4}" = "cpio" ]; then
357 KERNCMDLINE="vga=0 uvesafb.mode_option=640x480-32 root=/dev/ram0 rw mem=$QEMU_MEMORY $KERNEL_NETWORK_CMD"
358 QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE -initrd $ROOTFS $QEMU_UI_OPTIONS"
359 fi
360
361 if [ "$FSTYPE" = "nfs" ]; then
362 if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then
363 echo "Error: NFS mount point $ROOTFS doesn't exist."
364 cleanup
365 return 1
366 fi
367 KERNCMDLINE="root=/dev/nfs nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
368 QEMUOPTIONS="$QEMU_NETWORK_CMD $QEMU_UI_OPTIONS"
369 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500370 if [ "$IS_VM" = "true" ]; then
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500371 QEMUOPTIONS="$QEMU_NETWORK_CMD $QEMU_UI_OPTIONS"
372 fi
373 # Currently oprofile's event based interrupt mode doesn't work(Bug #828) in
374 # qemux86 and qemux86-64. We can use timer interrupt mode for now.
375 KERNCMDLINE="$KERNCMDLINE oprofile.timer=1"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500376}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500377
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500378config_qemux86_64() {
379 set_mem_size 256
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500380 QEMU=qemu-system-x86_64
381 if [ "$KVM_ACTIVE" = "yes" ]; then
382 CPU_SUBTYPE=kvm64
383 else
384 CPU_SUBTYPE=core2duo
385 fi
386 if [ ! -z "$vga_option" ]; then
387 QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS"
388 else
389 QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS -vga vmware"
390 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500391 if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" -o "$FSTYPE" = "wic" ]; then
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500392 KERNCMDLINE="vga=0 uvesafb.mode_option=640x480-32 root=$DROOT rw mem=$QEMU_MEMORY $KERNEL_NETWORK_CMD"
393 QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE $ROOTFS_OPTIONS $QEMU_UI_OPTIONS"
394 fi
395 if [ "$FSTYPE" = "nfs" ]; then
396 if [ "x$ROOTFS" = "x" ]; then
397 ROOTFS=/srv/nfs/qemux86-64
398 fi
399 if [ ! -d "$ROOTFS" ]; then
400 echo "Error: NFS mount point $ROOTFS doesn't exist."
401 cleanup
402 return 1
403 fi
404 KERNCMDLINE="root=/dev/nfs nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
405 QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE $QEMU_UI_OPTIONS"
406 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500407 if [ "$IS_VM" = "true" ]; then
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500408 QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE $QEMU_UI_OPTIONS"
409 fi
410 # Currently oprofile's event based interrupt mode doesn't work(Bug #828) in
411 # qemux86 and qemux86-64. We can use timer interrupt mode for now.
412 KERNCMDLINE="$KERNCMDLINE oprofile.timer=1"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500413}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500414
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500415config_qemumips() {
416 set_mem_size 256
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500417 case "$MACHINE" in
418 qemumips) QEMU=qemu-system-mips ;;
419 qemumipsel) QEMU=qemu-system-mipsel ;;
420 qemumips64) QEMU=qemu-system-mips64 ;;
421 esac
422 MACHINE_SUBTYPE=malta
423 QEMU_UI_OPTIONS="-vga cirrus $QEMU_UI_OPTIONS"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500424 if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" -o "$FSTYPE" = "wic" ]; then
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500425 #KERNCMDLINE="root=/dev/hda console=ttyS0 console=tty0 $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500426 KERNCMDLINE="root=$DROOT rw console=ttyS0 console=tty $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
427 QEMUOPTIONS="$QEMU_NETWORK_CMD -M $MACHINE_SUBTYPE $ROOTFS_OPTIONS -no-reboot $QEMU_UI_OPTIONS"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500428 fi
429 if [ "$FSTYPE" = "nfs" ]; then
430 if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then
431 echo "Error: NFS mount point $ROOTFS doesn't exist"
432 cleanup
433 return 1
434 fi
435 KERNCMDLINE="root=/dev/nfs console=ttyS0 console=tty nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
436 QEMUOPTIONS="$QEMU_NETWORK_CMD -M $MACHINE_SUBTYPE -no-reboot $QEMU_UI_OPTIONS"
437 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500438}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500439
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500440config_qemuppc() {
441 set_mem_size 256
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500442 QEMU=qemu-system-ppc
443 MACHINE_SUBTYPE=mac99
444 CPU_SUBTYPE=G4
445 QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS"
446 if [ "$SLIRP_ENABLED" = "yes" ]; then
447 QEMU_NETWORK_CMD=""
448 else
449 QEMU_NETWORK_CMD="-net nic,model=pcnet $QEMU_TAP_CMD"
450 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500451 if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" -o "$FSTYPE" = "wic" ]; then
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500452 KERNCMDLINE="root=$DROOT rw console=ttyS0 console=tty $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
453 QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE -M $MACHINE_SUBTYPE $ROOTFS_OPTIONS -no-reboot $QEMU_UI_OPTIONS"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500454 fi
455 if [ "$FSTYPE" = "nfs" ]; then
456 if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then
457 echo "Error: NFS mount point $ROOTFS doesn't exist"
458 cleanup
459 return 1
460 fi
461 KERNCMDLINE="root=/dev/nfs console=ttyS0 console=tty nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
462 QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE -M $MACHINE_SUBTYPE -no-reboot $QEMU_UI_OPTIONS"
463 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500464}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500465
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500466config_qemush4() {
467 set_mem_size 1024
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500468 QEMU=qemu-system-sh4
469 MACHINE_SUBTYPE=r2d
470 QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500471 if [ "${FSTYPE:0:3}" = "ext" -o "$FSTYPE" = "btrfs" -o "$FSTYPE" = "wic" ]; then
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500472 #KERNCMDLINE="root=/dev/hda console=ttyS0 console=tty0 $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
473 KERNCMDLINE="root=/dev/hda rw console=ttySC1 noiotrap earlyprintk=sh-sci.1 console=tty $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
474 QEMUOPTIONS="$QEMU_NETWORK_CMD -M $MACHINE_SUBTYPE -hda $ROOTFS -no-reboot $QEMU_UI_OPTIONS -monitor null -serial vc -serial stdio"
475 SERIALSTDIO="1"
476 fi
477 if [ "$FSTYPE" = "nfs" ]; then
478 if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then
479 echo "Error: NFS mount point $ROOTFS doesn't exist"
480 cleanup
481 return 1
482 fi
483 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"
484 QEMUOPTIONS="$QEMU_NETWORK_CMD -M $MACHINE_SUBTYPE -no-reboot $QEMU_UI_OPTIONS -monitor null -serial vc -serial stdio"
485 SERIALSTDIO="1"
486 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500487}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500488
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500489config_qemuzynq() {
490 set_mem_size 1024
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500491 QEMU=qemu-system-arm
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500492 QEMU_SYSTEM_OPTIONS="$QEMU_NETWORK_CMD -M xilinx-zynq-a9 -serial null -serial mon:stdio -dtb $KERNEL-$MACHINE.dtb"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500493 # zynq serial ports are named 'ttyPS0' and 'ttyPS1', fixup the default values
494 SCRIPT_KERNEL_OPT=$(echo "$SCRIPT_KERNEL_OPT" | sed 's/console=ttyS/console=ttyPS/g')
495 if [ "${FSTYPE:0:3}" = "ext" -o "${FSTYPE:0:4}" = "cpio" ]; then
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500496 KERNCMDLINE="earlyprintk root=/dev/ram rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500497 QEMUOPTIONS="$QEMU_SYSTEM_OPTIONS -initrd $ROOTFS"
498 fi
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500499}
500
501config_qemumicroblaze() {
502 set_mem_size 256
503 QEMU=qemu-system-microblazeel
504 QEMU_SYSTEM_OPTIONS="$QEMU_NETWORK_CMD -M petalogix-ml605 -serial mon:stdio"
505 if [ "${FSTYPE:0:3}" = "ext" -o "${FSTYPE:0:4}" = "cpio" ]; then
506 KERNCMDLINE="earlyprintk root=/dev/ram rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
507 QEMUOPTIONS="$QEMU_SYSTEM_OPTIONS -initrd $ROOTFS"
508 fi
509}
510
511case "$MACHINE" in
512 "qemuarm" | "qemuarmv6" | "qemuarmv7")
513 config_qemuarm
514 ;;
515 "qemuarm64")
516 config_qemuarm64
517 ;;
518 "qemux86")
519 config_qemux86
520 ;;
521 "qemux86-64")
522 config_qemux86_64
523 ;;
524 "qemumips" | "qemumipsel" | "qemumips64")
525 config_qemumips
526 ;;
527 "qemuppc")
528 config_qemuppc
529 ;;
530 "qemush4")
531 config_qemush4
532 ;;
533 "qemuzynq")
534 config_qemuzynq
535 ;;
536 "qemumicroblaze")
537 config_qemumicroblaze
538 ;;
539 *)
540 echo "Error: Unsupported machine type $MACHINE"
541 return 1
542 ;;
543esac
544
545# We need to specify -m <mem_size> to overcome a bug in qemu 0.14.0
546# https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/584480
547if [ -z "$mem_set" ] ; then
548 SCRIPT_QEMU_EXTRA_OPT="$SCRIPT_QEMU_EXTRA_OPT -m $mem_size"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500549fi
550
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500551if [ "${FSTYPE:0:3}" = "ext" ]; then
552 KERNCMDLINE="$KERNCMDLINE rootfstype=$FSTYPE"
553fi
554
555if [ "$FSTYPE" = "cpio.gz" ]; then
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500556 QEMUOPTIONS="-initrd $ROOTFS -nographic"
557 KERNCMDLINE="root=/dev/ram0 console=ttyS0 debugshell"
558fi
559
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500560if [ "$FSTYPE" = "iso" ]; then
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500561 QEMUOPTIONS="$QEMU_NETWORK_CMD -cdrom $ROOTFS $QEMU_UI_OPTIONS"
562fi
563
564if [ "x$QEMUOPTIONS" = "x" ]; then
565 echo "Error: Unable to support this combination of options"
566 cleanup
567 return 1
568fi
569
570if [ "$TCPSERIAL_PORTNUM" != "" ]; then
571 if [ "$MACHINE" = "qemuarm64" ]; then
572 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"
573 else
574 SCRIPT_QEMU_EXTRA_OPT="$SCRIPT_QEMU_EXTRA_OPT -serial tcp:127.0.0.1:$TCPSERIAL_PORTNUM"
575 fi
576fi
577
578PATH=$OECORE_NATIVE_SYSROOT/usr/bin:$PATH
579
580QEMUBIN=`which $QEMU 2> /dev/null`
581if [ ! -x "$QEMUBIN" ]; then
582 echo "Error: No QEMU binary '$QEMU' could be found."
583 cleanup
584 return 1
585fi
586
587NEED_GL=`ldd $QEMUBIN/$QEMU 2>&1 | grep libGLU`
588# We can't run without a libGL.so
589if [ "$NEED_GL" != "" ]; then
590 libgl='no'
591
592 [ -e /usr/lib/libGL.so -a -e /usr/lib/libGLU.so ] && libgl='yes'
593 [ -e /usr/lib64/libGL.so -a -e /usr/lib64/libGLU.so ] && libgl='yes'
594 [ -e /usr/lib/*-linux-gnu/libGL.so -a -e /usr/lib/*-linux-gnu/libGLU.so ] && libgl='yes'
595
596 if [ "$libgl" != 'yes' ]; then
597 echo "You need libGL.so and libGLU.so to exist in your library path to run the QEMU emulator.
598 Ubuntu package names are: libgl1-mesa-dev and libglu1-mesa-dev.
599 Fedora package names are: mesa-libGL-devel mesa-libGLU-devel."
600 return 1;
601 fi
602fi
603
604do_quit() {
605 cleanup
606 return 1
607}
608
609trap do_quit INT TERM QUIT
610
611# qemu got segfault if linked with nVidia's libgl
612GL_LD_PRELOAD=$LD_PRELOAD
613
614if ldd $QEMUBIN | grep -i nvidia &> /dev/null
615then
616cat << EOM
617WARNING: nVidia proprietary OpenGL libraries detected.
618nVidia's OpenGL libraries are known to have compatibility issues with qemu,
619resulting in a segfault. Please uninstall these drivers or ensure the mesa libGL
620libraries precede nvidia's via LD_PRELOAD(Already do it on Ubuntu 10).
621EOM
622
623# Automatically use Ubuntu system's mesa libGL, other distro can add its own path
624if grep -i ubuntu /etc/lsb-release &> /dev/null
625then
626 # precede nvidia's driver on Ubuntu 10
627 UBUNTU_MAIN_VERSION=`cat /etc/lsb-release |grep DISTRIB_RELEASE |cut -d= -f 2| cut -d. -f 1`
628 if [ "$UBUNTU_MAIN_VERSION" = "10" ];
629 then
630 GL_PATH=""
631 if test -e /usr/lib/libGL.so
632 then
633 GL_PATH="/usr/lib/libGL.so"
634 elif test -e /usr/lib/x86_64-linux-gnu/libGL.so
635 then
636 GL_PATH="/usr/lib/x86_64-linux-gnu/libGL.so"
637 fi
638
639 echo "Skip nVidia's libGL on Ubuntu 10!"
640 GL_LD_PRELOAD="$GL_PATH $LD_PRELOAD"
641 fi
642fi
643fi
644
645if [ "x$SERIALSTDIO" = "x1" ]; then
646 echo "Interrupt character is '^]'"
647 stty intr ^]
648fi
649
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500650
651# Preserve the multiplexing behavior for the monitor that would be there based
652# on whether nographic is used.
653if echo "$QEMUOPTIONS $SERIALOPTS $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT" | grep -- "-nographic"; then
654 FIRST_SERIAL_OPT="-serial mon:stdio"
655else
656 FIRST_SERIAL_OPT="-serial mon:vc"
657fi
658
659# qemuarm64 uses virtio for any additional serial ports so the normal mechanism
660# of using -serial will not work
661if [ "$MACHINE" = "qemuarm64" ]; then
662 SECOND_SERIAL_OPT="$SCRIPT_QEMU_EXTRA_OPT -device virtio-serial-device -chardev null,id=virtcon -device virtconsole,chardev=virtcon"
663else
664 SECOND_SERIAL_OPT="-serial null"
665fi
666
667# We always want a ttyS1. Since qemu by default adds a serial port when
668# nodefaults is not specified, it seems that all that would be needed is to
669# make sure a "-serial" is there. However, it appears that when "-serial" is
670# specified, it ignores the default serial port that is normally added.
671# So here we make sure to add two -serial if there are none. And only one
672# if there is one -serial already.
673NUM_SERIAL_OPTS=`echo $QEMUOPTIONS $SERIALOPTS $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT | sed -e 's/ /\n/g' | grep --count -- -serial`
674
675if [ "$NUM_SERIAL_OPTS" = "0" ]; then
676 SCRIPT_QEMU_EXTRA_OPT="$SCRIPT_QEMU_EXTRA_OPT $FIRST_SERIAL_OPT $SECOND_SERIAL_OPT"
677elif [ "$NUM_SERIAL_OPTS" = "1" ]; then
678 SCRIPT_QEMU_EXTRA_OPT="$SCRIPT_QEMU_EXTRA_OPT $SECOND_SERIAL_OPT"
679fi
680
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500681echo "Running $QEMU..."
682# -no-reboot is a mandatory option - see bug #100
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500683if [ "$IS_VM" = "true" ]; then
684 # Check root=/dev/sdX or root=/dev/vdX
685 [ ! -e "$VM" ] && error "VM image is not found!"
686 if grep -q 'root=/dev/sd' $VM; then
687 echo "Using scsi drive"
688 VM_DRIVE="-drive if=none,id=hd,file=$VM -device virtio-scsi-pci,id=scsi -device scsi-hd,drive=hd"
689 elif grep -q 'root=/dev/hd' $VM; then
690 echo "Using ide drive"
691 VM_DRIVE="$VM"
692 else
693 echo "Using virtio block drive"
694 VM_DRIVE="-drive if=virtio,file=$VM"
695 fi
696 QEMU_FIRE="$QEMUBIN $VM_DRIVE $QEMUOPTIONS $SERIALOPTS -no-reboot $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT"
697 echo $QEMU_FIRE
698 LD_PRELOAD="$GL_LD_PRELOAD" $QEMU_FIRE
699elif [ "$FSTYPE" = "iso" -o "$FSTYPE" = "wic" ]; then
700 QEMU_FIRE="$QEMUBIN $QEMUOPTIONS $SERIALOPTS -no-reboot $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT"
701 echo $QEMU_FIRE
702 LD_PRELOAD="$GL_LD_PRELOAD" $QEMU_FIRE
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500703else
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500704 QEMU_FIRE="$QEMUBIN -kernel $KERNEL $QEMUOPTIONS $SLIRP_CMD $SERIALOPTS -no-reboot $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT"
705 echo $QEMU_FIRE -append '"'$KERNCMDLINE $SCRIPT_KERNEL_OPT'"'
706 LD_PRELOAD="$GL_LD_PRELOAD" $QEMU_FIRE -append "$KERNCMDLINE $SCRIPT_KERNEL_OPT"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500707fi
708ret=$?
709if [ "$SLIRP_ENABLED" != "yes" ]; then
710 cleanup
711fi
712
713#set the original stty values before exit
714stty ${ORIG_STTY}
715trap - INT TERM QUIT
716
717return $ret