1# QEMU 2 3Zircon can [run under 4emulation](https://fuchsia.googlesource.com/docs/+/master/getting_started.md#Boot-from-QEMU) 5using QEMU. QEMU can either be installed via prebuilt binaries, or built 6locally. 7 8## Install Prebuilt QEMU 9 10QEMU is downloaded by the script that is used to download all Zircon 11prebuilts, including toolchains: 12 13``` 14./scripts/download-prebuilt 15``` 16 17This will download QEMU to the `prebuilt/downloads/qemu` directory. You 18can either add `prebuilt/downloads/qemu/bin` to your PATH, or specify 19`prebuilt/downloads/qemu/bin` using the -q flag to the run-zircon scripts 20(see below). 21 22## Build QEMU 23 24### Install Prerequisites 25 26Building QEMU on macOS requires a few packages. As of macOS 10.12.1: 27 28``` 29# Using http://brew.sh 30brew install pkg-config glib automake libtool 31 32# Or use http://macports.org ("port install ...") or build manually 33``` 34 35### Build 36 37``` 38cd $SRC 39git clone --recursive https://fuchsia.googlesource.com/third_party/qemu 40cd qemu 41./configure --target-list=aarch64-softmmu,x86_64-softmmu 42make -j32 43sudo make install 44``` 45 46If you don't want to install in /usr/local (the default), which will require you 47to be root, add --prefix=/path/to/install (perhaps $HOME/qemu). Then you'll 48either need to add /path/to/install/bin to your PATH or use -q /path/to/install 49when invoking run-zircon-{arch}. 50 51## Run Zircon under QEMU 52 53``` 54# for aarch64 55./scripts/run-zircon-arm64 56 57# for x86 58./scripts/run-zircon-x64 59``` 60 61If QEMU is not on your path, use -q <directory> to specify its location. 62 63The -h flag will list a number of options, including things like -b to rebuild 64first if necessary and -g to run with a graphical framebuffer. 65 66To exit qemu, enter Ctrl-a x. Use Ctrl-a h to see other commands. 67 68## Enabling Networking under QEMU 69 70The run-zircon script, when given the -N argument will attempt to create 71a network interface using the Linux tun/tap network device named "qemu". QEMU 72does not need to be run with any special privileges for this, but you need to 73create a persistent tun/tap device ahead of time (which does require you be root): 74 75On Linux: 76 77``` 78sudo apt-get install uml-utilities 79sudo tunctl -u $USER -t qemu 80sudo ifconfig qemu up 81``` 82 83This is sufficient to enable link local IPv6 (as the loglistener tool uses). 84 85On macOS: 86 87macOS does not support tun/tap devices out of the box; however, there is a widely 88used set of kernel extensions called tuntaposx which can be downloaded 89[here](http://tuntaposx.sourceforge.net/download.xhtml). Once the installer 90completes, the extensions will create up to 16 tun/tap devices. The 91run-zircon-x64 script uses /dev/tap0. 92 93``` 94sudo chown $USER /dev/tap0 95 96# Run zircon in QEMU, which will open /dev/tap0 97./scripts/run-zircon-x86 -N 98 99# (In a different window) bring up tap0 with a link local IPv6 address 100sudo ifconfig tap0 inet6 fc00::/7 up 101``` 102 103**NOTE**: One caveat with tuntaposx is that the network interface will 104automatically go down when QEMU exits and closes the network device. So the 105network interface needs to be brought back up each time QEMU is restarted. To 106automate this, you can use the -u flag to run a script on qemu startup. An 107example startup script containing the above command is located in 108scripts/qemu-ifup-macos, so QEMU can be started with: 109 110``` 111./scripts/run-zircon-x64 -Nu ./scripts/qemu-ifup-macos 112``` 113 114## Using Emulated Disk under QEMU 115 116Please follow the minfs instructions on how to create a disk image 117[here][minfs-create-image]. 118 119After creating the image, you can run zircon in QEMU with the disk image: 120``` 121./scripts/run-zircon-x64 -d [-D <disk_image_path (default: "blk.bin")>] 122``` 123 124 125## Debugging the kernel with GDB 126 127### Sample session 128 129Here is a sample session to get you started. 130 131In the shell you're running QEMU in: 132 133``` 134shell1$ ./scripts/run-zircon-x64 -- -s -S 135[... some QEMU start up text ...] 136``` 137 138This will start QEMU but freeze the system at startup, 139waiting for you to resume it with "continue" in GDB. 140If you want to run QEMU without GDB, but be able to attach with GDB later 141then start QEMU without "-S" in the above example: 142 143``` 144shell1$ ./scripts/run-zircon-x64 -- -s 145[... some QEMU start up text ...] 146``` 147 148And then in the shell you're running GDB in: 149[Commands here are fully spelled out, but remember most can be abbreviated.] 150 151``` 152shell2$ gdb build-x86/zircon.elf 153(gdb) target extended-remote :1234 154Remote debugging using :1234 1550x000000000000fff0 in ?? () 156(gdb) # Don't try to do too much at this point. 157(gdb) # GDB can't handle architecture switching in one session, 158(gdb) # and at this point the architecture is 16-bit x86. 159(gdb) break lk_main 160Breakpoint 1 at 0xffffffff8010cb58: file kernel/top/main.c, line 59. 161(gdb) continue 162Continuing. 163 164Breakpoint 1, lk_main (arg0=1, arg1=18446744071568293116, arg2=0, arg3=0) 165 at kernel/top/main.c:59 16659 { 167(gdb) continue 168``` 169 170At this point Zircon boots and back in shell1 you'll be at the Zircon 171prompt. 172 173``` 174mxsh> 175``` 176 177If you Ctrl-C in shell2 at this point you can get back to GDB. 178 179``` 180(gdb) # Having just done "continue" 181^C 182Program received signal SIGINT, Interrupt. 183arch_idle () at kernel/arch/x86/64/ops.S:32 18432 ret 185(gdb) info threads 186 Id Target Id Frame 187 4 Thread 4 (CPU#3 [halted ]) arch_idle () at kernel/arch/x86/64/ops.S:32 188 3 Thread 3 (CPU#2 [halted ]) arch_idle () at kernel/arch/x86/64/ops.S:32 189 2 Thread 2 (CPU#1 [halted ]) arch_idle () at kernel/arch/x86/64/ops.S:32 190* 1 Thread 1 (CPU#0 [halted ]) arch_idle () at kernel/arch/x86/64/ops.S:32 191``` 192 193QEMU reports one thread to GDB for each CPU. 194 195### The zircon.elf-gdb.py script 196 197The scripts/zircon.elf-gdb.py script is automagically loaded by gdb. 198It provides several things: 199 200- Pretty-printers for zircon objects (alas none at the moment). 201 202- Several zircon specific commands, all with a "zircon" prefix. To see them: 203``` 204(gdb) help info zircon 205(gdb) help set zircon 206(gdb) help show zircon 207``` 208 209- Enhanced unwinder support for automagic unwinding through kernel faults. 210 211Heads up: This script isn't always updated as zircon changes. 212 213### Terminating the session 214 215To terminate QEMU you can send commands to QEMU from GDB: 216 217``` 218(gdb) monitor quit 219(gdb) quit 220``` 221 222### Interacting with QEMU from Gdb 223 224To see the list of QEMU commands you can execute from GDB: 225 226``` 227(gdb) monitor help 228``` 229 230### Saving system state for debugging 231 232If you have a crash that is difficult to debug, or that you need help 233with debugging, it's possible to save system state akin to a core dump. 234 235``` 236bash$ qemu-img create -f qcow2 /tmp/my_snapshots.qcow2 32M 237``` 238 239will create a "32M" block storage device. Next launch QEMU and tell it 240about the device, but don't tell it to attach the device to the guest system. 241This is OK; we don't plan on using it to back up the disk state, we just want 242a core dump. Note: all of this can be skipped if you are already emulating 243a block device and it is using the qcow2 format. 244 245``` 246bash$ qemu <normal_launch_args> -drive if=none,format=qcow2,file=/tmp/my_snapshots.qcow2 247``` 248 249When you get to a point where you want to save the core state, drop to the QEMU 250console using <C-a><C-c>. You should get the (qemu) prompt at this point. 251From here, just say: 252 253``` 254(qemu) savevm my_backup_tag_name 255``` 256 257Later on, from an identical machine (one launched with the same args as before), 258you can drop to the console and run: 259 260``` 261(qemu) loadvm my_backup_tag_name 262``` 263 264to restore the state. Alternatively, you can do it from the cmd line with: 265 266``` 267bash$ qemu <normal_launch_args> -drive if=none,format=qcow2,file=/tmp/my_snapshots.qcow2 -loadvm my_backup_tag_name 268``` 269 270In theory, you could package up the qcow2 image along with your build output 271directory and anyone should be able to restore your state and start to poke 272at stuff from the QEMU console. 273 274 275[minfs-create-image]: https://fuchsia.googlesource.com/zircon/+/master/docs/minfs.md#Host-Device-QEMU-Only 276