poky-qemu-internal 13 KB

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