runqemu-internal 25 KB

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