poky-qemu-internal 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. #!/bin/bash -x
  2. # Handle running Poky images under qemu
  3. #
  4. # Copyright (C) 2006-2008 OpenedHand Ltd.
  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. # CROSSPATH - the path to any cross toolchain to use with distcc
  22. #
  23. # Image options:
  24. # MACHINE - the machine to run
  25. # FSTYPE - the image type to run
  26. # KERNEL - the kernel image file to use
  27. # ROOTFS - the disk image file to use
  28. #
  29. mem_size=-1
  30. #Get rid of <> and get the contents of extra qemu running params
  31. SCRIPT_QEMU_EXTRA_OPT=`echo $SCRIPT_QEMU_EXTRA_OPT | sed -e 's/<//' -e 's/>//'`
  32. #if user set qemu memory, eg: -m 256 in qemu extra params, we need to do some
  33. # validation check
  34. mem_set=`expr "$SCRIPT_QEMU_EXTRA_OPT" : '.*\(-m[[:space:]] *[0-9]*\)'`
  35. if [ ! -z "$mem_set" ] ; then
  36. #Get memory setting size from user input
  37. mem_size=`echo $mem_set | sed 's/-m[[:space:]] *//'`
  38. fi
  39. if [ $mem_size -gt 0 ]; then
  40. QEMU_MEMORY="$mem_size"M
  41. fi
  42. if [ -z "$QEMU_MEMORY" ]; then
  43. case "$MACHINE" in
  44. "qemux86")
  45. QEMU_MEMORY="128M"
  46. ;;
  47. "qemux86-64")
  48. QEMU_MEMORY="128M"
  49. ;;
  50. "qemuarm")
  51. QEMU_MEMORY="128M"
  52. ;;
  53. "qemumips")
  54. QEMU_MEMORY="128M"
  55. ;;
  56. "qemuppc")
  57. QEMU_MEMORY="128M"
  58. ;;
  59. *)
  60. QEMU_MEMORY="64M"
  61. ;;
  62. esac
  63. fi
  64. # Bug 433: qemuarm cannot use > 128 MB RAM
  65. if [ "$MACHINE" = "qemuarm" ]; then
  66. RAM=`echo $QEMU_MEMORY | sed 's/M$//'`
  67. if [[ -z "$RAM" || $RAM -gt 128 ]]; then
  68. echo "WARNING: qemuarm does not support > 128M of RAM."
  69. echo "Changing QEMU_MEMORY to default of 128M."
  70. QEMU_MEMORY="128M"
  71. SCRIPT_QEMU_EXTRA_OPT=`echo $SCRIPT_QEMU_EXTRA_OPT | sed -e "s/$mem_set/-m 128/" `
  72. fi
  73. fi
  74. # This file is created when poky-gen-tapdevs creates a bank of tap
  75. # devices, indicating that the user should not bring up new ones using
  76. # sudo.
  77. NOSUDO_FLAG="/etc/poky-nosudo"
  78. QEMUIFUP=`which poky-qemu-ifup`
  79. QEMUIFDOWN=`which poky-qemu-ifdown`
  80. NFSRUNNING="false"
  81. acquire_lock() {
  82. lockfile=$1
  83. if [ -z "$lockfile" ]; then
  84. echo "Error: missing lockfile arg passed to acquire_lock()"
  85. return 1
  86. fi
  87. if [ -e "$lockfile.lock" ]; then
  88. # Check that the lockfile is not stale
  89. ps=`ps -ewwo pid | grep $(cat $lockfile.lock)`
  90. if [ -z "$ps" ]; then
  91. echo "WARNING: Stale lock file detected, deleting $lockfile.lock."
  92. rm -f $lockfile.lock
  93. echo $$ > $lockfile.lock
  94. else
  95. return 1
  96. fi
  97. else
  98. echo $$ > $lockfile.lock
  99. fi
  100. return 0
  101. }
  102. release_lock() {
  103. lockfile=$1
  104. if [ -z "$lockfile" ]; then
  105. echo "Error: missing lockfile arg passed to release_lock()"
  106. return 1
  107. fi
  108. rm -f $lockfile.lock
  109. }
  110. LOCKDIR="/tmp/qemu-tap-locks"
  111. if [ ! -d "$LOCKDIR" ]; then
  112. mkdir $LOCKDIR
  113. chmod 777 $LOCKDIR
  114. fi
  115. IFCONFIG=`which ifconfig`
  116. if [ -z "$IFCONFIG" ]; then
  117. IFCONFIG=/sbin/ifconfig
  118. fi
  119. POSSIBLE=`$IFCONFIG -a | grep '^tap' | awk '{print $1}'`
  120. TAP=""
  121. LOCKFILE=""
  122. for tap in $POSSIBLE; do
  123. LOCKFILE="$LOCKDIR/$tap"
  124. echo "Acquiring lockfile for $tap..."
  125. acquire_lock $LOCKFILE
  126. if [ $? -eq 0 ]; then
  127. TAP=$tap
  128. break
  129. fi
  130. done
  131. if [ "$TAP" = "" ]; then
  132. if [ -e "$NOSUDO_FLAG" ]; then
  133. echo "Error: There are no available tap devices to use for networking,"
  134. echo "and I see $NOSUDO_FLAG exists, so I am not going to try creating"
  135. echo "a new one with sudo."
  136. exit 1
  137. fi
  138. GROUPID=`id -g`
  139. echo "Setting up tap interface under sudo"
  140. tap=`sudo $QEMUIFUP $GROUPID $POKY_NATIVE_SYSROOT`
  141. if [ $? -ne 0 ]; then
  142. # Re-run standalone to see verbose errors
  143. sudo $QEMUIFUP $GROUPID $POKY_NATIVE_SYSROOT
  144. return
  145. fi
  146. LOCKFILE="$LOCKDIR/$tap"
  147. echo "Acquiring lockfile for $tap..."
  148. acquire_lock $LOCKFILE
  149. if [ $? -eq 0 ]; then
  150. TAP=$tap
  151. fi
  152. else
  153. echo "Using preconfigured tap device '$TAP'"
  154. fi
  155. cleanup() {
  156. if [ ! -e "$NOSUDO_FLAG" ]; then
  157. sudo $QEMUIFDOWN $TAP $POKY_NATIVE_SYSROOT
  158. fi
  159. echo "Releasing lockfile of preconfigured tap device '$TAP'"
  160. release_lock $LOCKFILE
  161. if [ "$NFSRUNNING" = "true" ]; then
  162. echo "Shutting down the userspace NFS server..."
  163. echo "poky-export-rootfs stop $ROOTFS"
  164. poky-export-rootfs stop $ROOTFS
  165. fi
  166. # If QEMU crashes or somehow tty properties are not restored
  167. # after qemu exits, we need to run stty sane
  168. stty sane
  169. }
  170. n1=$[ (`echo $TAP | sed 's/tap//'` * 2) + 1 ]
  171. n2=$[ (`echo $TAP | sed 's/tap//'` * 2) + 2 ]
  172. KERNEL_NETWORK_CMD="ip=192.168.7.$n2::192.168.7.$n1:255.255.255.0"
  173. QEMU_TAP_CMD="-net tap,vlan=0,ifname=$TAP,script=no,downscript=no"
  174. QEMU_NETWORK_CMD="-net nic,vlan=0 $QEMU_TAP_CMD"
  175. KERNCMDLINE="mem=$QEMU_MEMORY"
  176. QEMU_UI_OPTIONS="-show-cursor -usb -usbdevice wacom-tablet"
  177. NFS_INSTANCE=`echo $TAP | sed 's/tap//'`
  178. export NFS_INSTANCE
  179. SERIALOPTS=""
  180. if [ "x$SERIAL_LOGFILE" != "x" ]; then
  181. SERIALOPTS="-serial file:$SERIAL_LOGFILE"
  182. fi
  183. case "$MACHINE" in
  184. "qemuarm") ;;
  185. "qemumips") ;;
  186. "qemuppc") ;;
  187. "qemuarmv6") ;;
  188. "qemuarmv7") ;;
  189. "qemux86") ;;
  190. "qemux86-64") ;;
  191. "akita") ;;
  192. "spitz") ;;
  193. *)
  194. echo "Error: Unsupported machine type $MACHINE"
  195. return
  196. ;;
  197. esac
  198. if [ ! -f "$KERNEL" ]; then
  199. echo "Error: Kernel image file $KERNEL doesn't exist"
  200. cleanup
  201. return
  202. fi
  203. if [ "$FSTYPE" != "nfs" -a ! -f "$ROOTFS" ]; then
  204. echo "Error: Image file $ROOTFS doesn't exist"
  205. cleanup
  206. return
  207. fi
  208. if [ "$FSTYPE" = "nfs" ]; then
  209. NFS_SERVER="192.168.7.1"
  210. NFS_DIR=`echo $ROOTFS | sed 's/^[^:]*:\(.*\)/\1/'`
  211. MOUNTD_PORT=$[ 21111 + $NFS_INSTANCE ]
  212. NFSD_PORT=$[ 11111 + $NFS_INSTANCE ]
  213. UNFS_OPTS="nfsvers=2,mountprog=$MOUNTD_PORT,nfsprog=$NFSD_PORT,udp"
  214. PSEUDO_LOCALSTATEDIR=~/.poky-sdk/pseudo
  215. export PSEUDO_LOCALSTATEDIR
  216. rpcbind_running=`ps ax | grep rpcbind | grep -v grep | wc -l`
  217. portmap_running=`ps ax | grep portmap | grep -v grep | wc -l`
  218. if [[ $rpcbind_running == 0 && $portmap_running == 0 ]]; then
  219. echo "You need to be running either rpcbind or portmap to continue"
  220. cleanup
  221. return
  222. fi
  223. # Start the userspace NFS server
  224. echo "poky-export-rootfs restart $ROOTFS"
  225. poky-export-rootfs restart $ROOTFS
  226. if [ $? != 0 ]; then
  227. cleanup
  228. return
  229. fi
  230. NFSRUNNING="true"
  231. fi
  232. if [ "$NFS_SERVER" = "" ]; then
  233. NFS_SERVER="192.168.7.1"
  234. NFS_DIR=$ROOTFS
  235. fi
  236. if [ "$MACHINE" = "qemuarm" -o "$MACHINE" = "qemuarmv6" -o "$MACHINE" = "qemuarmv7" ]; then
  237. QEMU=qemu-system-arm
  238. MACHINE_SUBTYPE=versatilepb
  239. QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS"
  240. # QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS -force-pointer"
  241. if [ "$FSTYPE" = "ext3" ]; then
  242. KERNCMDLINE="root=/dev/sda console=ttyAMA0,115200 console=tty $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY highres=off"
  243. QEMUOPTIONS="$QEMU_NETWORK_CMD -M versatilepb -hda $ROOTFS -no-reboot $QEMU_UI_OPTIONS"
  244. fi
  245. if [ "$FSTYPE" = "nfs" ]; then
  246. if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then
  247. echo "Error: NFS mount point $ROOTFS doesn't exist"
  248. cleanup
  249. return
  250. fi
  251. KERNCMDLINE="root=/dev/nfs nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
  252. QEMUOPTIONS="$QEMU_NETWORK_CMD -M versatilepb --no-reboot $QEMU_UI_OPTIONS"
  253. fi
  254. if [ "$MACHINE" = "qemuarmv6" ]; then
  255. QEMUOPTIONS="$QEMUOPTIONS -cpu arm1136"
  256. fi
  257. if [ "$MACHINE" = "qemuarmv7" ]; then
  258. QEMUOPTIONS="$QEMUOPTIONS -cpu cortex-a8"
  259. fi
  260. fi
  261. if [ "$MACHINE" = "qemux86" ]; then
  262. QEMU=qemu
  263. QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS -vga vmware -enable-gl"
  264. if [ "$FSTYPE" = "ext3" ]; then
  265. KERNCMDLINE="vga=0 root=/dev/hda mem=$QEMU_MEMORY $KERNEL_NETWORK_CMD"
  266. QEMUOPTIONS="$QEMU_NETWORK_CMD -hda $ROOTFS $QEMU_UI_OPTIONS"
  267. fi
  268. if [ "$FSTYPE" = "nfs" ]; then
  269. if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then
  270. echo "Error: NFS mount point $ROOTFS doesn't exist."
  271. cleanup
  272. return
  273. fi
  274. KERNCMDLINE="root=/dev/nfs nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
  275. QEMUOPTIONS="$QEMU_NETWORK_CMD $QEMU_UI_OPTIONS"
  276. fi
  277. # Currently oprofile's event based interrupt mode doesn't work(Bug #828) in
  278. # qemux86 and qemux86-64. We can use timer interrupt mode for now.
  279. KERNCMDLINE="$KERNCMDLINE oprofile.timer=1"
  280. fi
  281. if [ "$MACHINE" = "qemux86-64" ]; then
  282. QEMU=qemu-system-x86_64
  283. QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS -vga vmware -enable-gl"
  284. if [ "$FSTYPE" = "ext3" ]; then
  285. KERNCMDLINE="vga=0 root=/dev/hda mem=$QEMU_MEMORY $KERNEL_NETWORK_CMD"
  286. QEMUOPTIONS="$QEMU_NETWORK_CMD -hda $ROOTFS $QEMU_UI_OPTIONS"
  287. fi
  288. if [ "$FSTYPE" = "nfs" ]; then
  289. if [ "x$ROOTFS" = "x" ]; then
  290. ROOTFS=/srv/nfs/qemux86-64
  291. fi
  292. if [ ! -d "$ROOTFS" ]; then
  293. echo "Error: NFS mount point $ROOTFS doesn't exist."
  294. cleanup
  295. return
  296. fi
  297. KERNCMDLINE="root=/dev/nfs nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
  298. QEMUOPTIONS="$QEMU_NETWORK_CMD $QEMU_UI_OPTIONS"
  299. fi
  300. # Currently oprofile's event based interrupt mode doesn't work(Bug #828) in
  301. # qemux86 and qemux86-64. We can use timer interrupt mode for now.
  302. KERNCMDLINE="$KERNCMDLINE oprofile.timer=1"
  303. fi
  304. if [ "$MACHINE" = "spitz" ]; then
  305. QEMU=qemu-system-arm
  306. if [ "$FSTYPE" = "ext3" ]; then
  307. echo $ROOTFS
  308. ROOTFS=`readlink -f $ROOTFS`
  309. echo $ROOTFS
  310. if [ ! -e "$ROOTFS.qemudisk" ]; then
  311. echo "Adding a partition table to the ext3 image for use by QEMU, please wait..."
  312. poky-addptable2image $ROOTFS $ROOTFS.qemudisk
  313. fi
  314. QEMUOPTIONS="$QEMU_NETWORK_CMD -M spitz -hda $ROOTFS.qemudisk -portrait"
  315. fi
  316. fi
  317. if [ "$MACHINE" = "qemumips" ]; then
  318. QEMU=qemu-system-mips
  319. MACHINE_SUBTYPE=malta
  320. QEMU_UI_OPTIONS="-vga cirrus $QEMU_UI_OPTIONS"
  321. if [ "$FSTYPE" = "ext3" ]; then
  322. #KERNCMDLINE="root=/dev/hda console=ttyS0 console=tty0 $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
  323. KERNCMDLINE="root=/dev/hda console=ttyS0 console=tty $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
  324. QEMUOPTIONS="$QEMU_NETWORK_CMD -M $MACHINE_SUBTYPE -hda $ROOTFS -no-reboot $QEMU_UI_OPTIONS"
  325. fi
  326. if [ "$FSTYPE" = "nfs" ]; then
  327. if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then
  328. echo "Error: NFS mount point $ROOTFS doesn't exist"
  329. cleanup
  330. return
  331. fi
  332. KERNCMDLINE="root=/dev/nfs console=ttyS0 console=tty nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
  333. QEMUOPTIONS="$QEMU_NETWORK_CMD -M $MACHINE_SUBTYPE -no-reboot $QEMU_UI_OPTIONS"
  334. fi
  335. fi
  336. if [ "$MACHINE" = "qemuppc" ]; then
  337. QEMU=qemu-system-ppc
  338. MACHINE_SUBTYPE=prep
  339. CPU_SUBTYPE=603e
  340. BIOS=powerpc_rom.bin
  341. QEMU_UI_OPTIONS="$QEMU_UI_OPTIONS -nographic"
  342. if [ "$FSTYPE" = "ext3" ]; then
  343. KERNCMDLINE="root=/dev/hda console=ttyS0 console=tty0 $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
  344. QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE -M $MACHINE_SUBTYPE -bios $BIOS -hda $ROOTFS -no-reboot $QEMU_UI_OPTIONS"
  345. fi
  346. if [ "$FSTYPE" = "nfs" ]; then
  347. if [ "$NFS_SERVER" = "192.168.7.1" -a ! -d "$NFS_DIR" ]; then
  348. echo "Error: NFS mount point $ROOTFS doesn't exist"
  349. cleanup
  350. return
  351. fi
  352. KERNCMDLINE="root=/dev/nfs console=ttyS0 console=tty0 nfsroot=$NFS_SERVER:$NFS_DIR,$UNFS_OPTS rw $KERNEL_NETWORK_CMD mem=$QEMU_MEMORY"
  353. QEMUOPTIONS="$QEMU_NETWORK_CMD -cpu $CPU_SUBTYPE -M $MACHINE_SUBTYPE -bios $BIOS -no-reboot $QEMU_UI_OPTIONS"
  354. fi
  355. fi
  356. if [ "$MACHINE" = "akita" ]; then
  357. QEMU=qemu-system-arm
  358. if [ "$FSTYPE" = "jffs2" ]; then
  359. ROOTFS=`readlink -f $ROOTFS`
  360. if [ ! -e "$ROOTFS.qemuflash" ]; then
  361. echo "Converting raw image into flash image format for use by QEMU, please wait..."
  362. raw2flash.akita < $ROOTFS > $ROOTFS.qemuflash
  363. fi
  364. QEMUOPTIONS="$QEMU_NETWORK_CMD -M akita -mtdblock $ROOTFS.qemuflash -portrait"
  365. fi
  366. fi
  367. if [ "x$QEMUOPTIONS" = "x" ]; then
  368. echo "Error: Unable to support this combination of options"
  369. cleanup
  370. return
  371. fi
  372. PATH=$CROSSPATH:$POKY_NATIVE_SYSROOT/usr/bin:$PATH
  373. QEMUBIN=`which $QEMU`
  374. if [ ! -x "$QEMUBIN" ]; then
  375. echo "Error: No QEMU binary '$QEMU' could be found."
  376. cleanup
  377. return
  378. fi
  379. function _quit() {
  380. if [ -n "$PIDFILE" ]; then
  381. #echo kill `cat $PIDFILE`
  382. kill `cat $PIDFILE`
  383. fi
  384. cleanup
  385. return
  386. }
  387. DISTCCD=`which distccd`
  388. PIDFILE=""
  389. trap _quit INT TERM QUIT
  390. if [ -x "$DISTCCD" ]; then
  391. echo "Starting distccd..."
  392. PIDFILE=`mktemp`
  393. $DISTCCD --allow 192.168.7.2 --daemon --pid-file $PIDFILE &
  394. else
  395. echo "WARNING: distccd not present, no distcc support loaded."
  396. fi
  397. # qemu got segfault if linked with nVidia's libgl
  398. if ldd $QEMUBIN | grep -i nvidia &> /dev/null
  399. then
  400. cat << EOM
  401. WARNING: nVidia proprietary OpenGL libraries detected.
  402. nVidia's OpenGL libraries are known to have compatibility issues with qemu,
  403. resulting in a segfault. Please uninstall these drivers or ensure the mesa libGL
  404. libraries precede nvidia's via LD_PRELOAD.
  405. EOM
  406. fi
  407. echo "Running $QEMU..."
  408. # -no-reboot is a mandatory option - see bug #100
  409. echo $QEMUBIN -kernel $KERNEL $QEMUOPTIONS $SERIALOPTS -no-reboot $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT --append '"'$KERNCMDLINE $SCRIPT_KERNEL_OPT'"'
  410. $QEMUBIN -kernel $KERNEL $QEMUOPTIONS $SERIALOPTS -no-reboot $SCRIPT_QEMU_OPT $SCRIPT_QEMU_EXTRA_OPT --append "$KERNCMDLINE $SCRIPT_KERNEL_OPT"
  411. cleanup
  412. trap - INT TERM QUIT
  413. return