Joakim Bech | 8e5c5b3 | 2018-10-25 08:18:32 +0200 | [diff] [blame] | 1 | On this page you will find device specific information for QEMU v7 (Armv7-A) and |
| 2 | QEMU v8 (Armv8-A). |
| 3 | |
| 4 | .. _qemu_v7: |
| 5 | |
| 6 | ####### |
| 7 | QEMU v7 |
| 8 | ####### |
| 9 | The instructions here will tell how to run OP-TEE using QEMU for Armv7-A. |
| 10 | |
| 11 | Build instructions |
| 12 | ****************** |
| 13 | As long as you pick the v7 manifest, i.e., ``default.xml`` the |
| 14 | ":ref:`get_and_build_the_solution`" tells all you need to know to build and boot |
| 15 | up QEMU v7. |
| 16 | |
| 17 | |
| 18 | Consoles |
| 19 | ******** |
| 20 | After running ``make run`` you will end up in the QEMU console and it will also |
| 21 | spawn two UART consoles. One console containing the UART for secure world and |
| 22 | one console containing the UART for normal world. You will see that it stops |
| 23 | waiting for input on the QEMU console. To continue, do: |
| 24 | |
| 25 | .. code-block:: none |
| 26 | |
| 27 | (qemu) c |
| 28 | |
| 29 | Host-Guest folder sharing |
| 30 | ************************* |
| 31 | You can use the VirtFS QEMU feature to avoid changing rootfs CPIO archive every |
| 32 | time you need to add additional files or modify existing files. To do this, you |
| 33 | share a folder between the guest and host operating systems. To enable and use |
| 34 | this feature you have to provide additional arguments when running make, |
| 35 | example: |
| 36 | |
| 37 | .. code-block:: bash |
| 38 | |
| 39 | $ make QEMU_VIRTFS_ENABLE=y QEMU_USERNET_ENABLE=y |
| 40 | |
| 41 | .. hint:: |
| 42 | |
| 43 | You can also add ``QEMU_VIRTFS_HOST_DIR=<share>`` in case you don't want to |
| 44 | use the default sharing location (which is the root of <qemu-v7-project>). |
| 45 | |
| 46 | When QEMU with OP-TEE is up and running, you can mount the host folder in QEMU |
| 47 | (normal world UART). |
| 48 | |
| 49 | .. code-block:: none |
| 50 | |
| 51 | # mount -t 9p -o trans=virtio host <mount_point> |
| 52 | |
| 53 | ``<mount_point>`` here is folder in the QEMU where you want to mount the host |
| 54 | PC's shared folder. So if you want to mount it at ``/mnt/host`` you typically do |
| 55 | this from QEMU NW/UART. |
| 56 | |
| 57 | .. code-block:: none |
| 58 | |
| 59 | # mkdir -p /mnt/host |
| 60 | # mount -t 9p -o trans=virtio host /mnt/host |
| 61 | |
| 62 | Networking |
| 63 | ********** |
| 64 | After booting QEMU, ``eth0`` will automatically receive an IP address from |
| 65 | QEMU via DHCP using the SLiRP user networking feature. QEMU will act as a |
| 66 | gateway to the host network `SLiRP`_. |
| 67 | |
| 68 | Please note that ICMP won't work in the guest unless additional configuration is |
| 69 | made, so the ``ping`` utility won't work. |
| 70 | |
| 71 | GDB - Normal world |
| 72 | ****************** |
| 73 | If you need to debug a client application, using GDB in a remote debugging |
| 74 | configuration may be useful. Remote debugging means ``gdb`` runs on your PC, |
| 75 | where it can access the source code, while the program being debugged runs on |
| 76 | the remote system (in this case, in the QEMU environment in normal world). Here |
| 77 | is how to do that. On your PC, build with ``GDBSERVER=y``: |
| 78 | |
| 79 | .. code-block:: bash |
| 80 | |
| 81 | $ cd <qemu-v7-project>/build |
| 82 | # You **only** need to rm -rf the first time you build with the new flag. |
| 83 | # If you omit doing so, it's likely that you will see "stamp" errors in the |
| 84 | # build log. |
| 85 | $ rm -rf <qemu-v7-project>/out-br |
| 86 | $ make -j8 run GDBSERVER=y |
| 87 | |
| 88 | Boot up as usual |
| 89 | |
| 90 | .. code-block:: bash |
| 91 | |
| 92 | (qemu) c |
| 93 | |
| 94 | Inside QEMU (Normal World UART), run your application with gdbserver (for |
| 95 | example ``xtest 4002``): |
| 96 | |
| 97 | .. code-block:: none |
| 98 | |
| 99 | # gdbserver :12345 xtest 4002 |
| 100 | Process xtest created; pid = 654 |
| 101 | Listening on port 12345 |
| 102 | |
| 103 | Back on your PC, open another terminal, start GDB and connect to the target: |
| 104 | |
| 105 | .. code-block:: bash |
| 106 | |
| 107 | $ <qemu-v7-project>/out-br/host/bin/arm-buildroot-linux-gnueabihf-gdb |
| 108 | (gdb) set sysroot <qemu-v7-project>/out-br/host/arm-buildroot-linux-gnueabihf/sysroot |
| 109 | (gdb) target remote :12345 |
| 110 | |
| 111 | Now GDB is connected to the remote application. You may use GDB normally. |
| 112 | |
| 113 | .. code-block:: none |
| 114 | |
| 115 | (gdb) b main |
| 116 | (gdb) c |
| 117 | |
Joakim Bech | 37b5436 | 2019-03-06 10:33:46 +0100 | [diff] [blame] | 118 | GDB - Secure world |
| 119 | ****************** |
| 120 | TEE core debugging |
| 121 | ================== |
| 122 | To debug TEE core running QEMU with GDB, you don't have to enable any special |
| 123 | flags as such, but it's easier to debug if you have optimization disabled. Other |
| 124 | than that you will have four consoles that you are working with. |
| 125 | |
| 126 | - Qemu console |
| 127 | - NW UART console |
| 128 | - SW UART console |
| 129 | - GDB console |
| 130 | |
| 131 | All of them but the GDB console are consoles you normally will see/use when |
| 132 | running OP-TEE/xtest using QEMU. The first thing is to start QEMU, i.e., |
| 133 | |
| 134 | .. code-block:: bash |
| 135 | |
| 136 | $ cd <qemu-v7-project>/build |
| 137 | # make run-only also works if you don't want to rebuild things |
| 138 | $ make run |
| 139 | |
| 140 | Next launch another console for GDB and do this |
| 141 | |
| 142 | .. code-block:: bash |
| 143 | |
| 144 | $ cd <qemu-v7-project>/toolchains/aarch32/bin |
| 145 | $ ./arm-linux-gnueabihf-gdb -q |
| 146 | |
| 147 | In the GDB console connect to the QEMU GDB server, like this (the output is |
| 148 | included to show what you normally will see). |
| 149 | |
| 150 | .. code-block:: none |
| 151 | |
| 152 | (gdb) target remote localhost:1234 |
| 153 | Remote debugging using localhost:1234 |
| 154 | warning: No executable has been specified and target does not support |
| 155 | determining executable automatically. Try using the "file" command. |
| 156 | 0x00000000 in ?? () |
| 157 | |
| 158 | Still in the GDB console, load the symbols for TEE core |
| 159 | |
| 160 | .. code-block:: none |
| 161 | |
| 162 | (gdb) symbol-file <qemu-v7-project>/optee_os/out/arm/core/tee.elf |
| 163 | Reading symbols from <qemu-v7-project>/optee_os/out/arm/core/tee.elf...done. |
| 164 | |
| 165 | Now you can set a breakpoint for any symbol in OP-TEE, for example |
| 166 | |
| 167 | .. code-block:: none |
| 168 | |
| 169 | (gdb) b tee_entry_std |
| 170 | Breakpoint 1 at 0xe103012: file core/arch/arm/tee/entry_std.c, line 526. |
| 171 | |
| 172 | Last step is to initiate the boot, do that also from the GDB console |
| 173 | |
| 174 | .. code-block:: none |
| 175 | |
| 176 | (gdb) c |
| 177 | Continuing. |
| 178 | |
| 179 | At this point will see UART output in the Normal world console as well as the |
| 180 | Secure world UART console. If you now for example :ref:`optee_test_run_xtest`, |
| 181 | then you will rather soon hit the breakpoint we previously set and you will see |
| 182 | something like this in the GDB console: |
| 183 | |
| 184 | .. code-block:: none |
| 185 | |
| 186 | Continuing. |
| 187 | [Switching to Thread 2] |
| 188 | |
| 189 | Thread 2 hit Breakpoint 1, tee_entry_std (smc_args=0xe183f18 |
| 190 | <stack_thread+8216>) at core/arch/arm/tee/entry_std.c:526 |
| 191 | 526 struct optee_msg_arg *arg = NULL; /* fix gcc warning */ |
| 192 | (gdb) |
| 193 | |
| 194 | From here you can start to poke around with GDB, single step, read memory, read |
| 195 | registers, print variables and all sorts of things that you normally do with a |
| 196 | debugger. |
| 197 | |
| 198 | .. hint:: |
| 199 | |
Joakim Bech | 9e7464b | 2019-05-21 11:40:28 +0200 | [diff] [blame^] | 200 | Some people find it easier to also see the source code while debugging. You |
| 201 | can enable the "TUI mode" to see the source code in GDB. To enable that, run |
| 202 | GDB with |
Joakim Bech | 37b5436 | 2019-03-06 10:33:46 +0100 | [diff] [blame] | 203 | |
| 204 | .. code-block:: bash |
| 205 | |
| 206 | $ ./arm-linux-gnueabihf-gdb -q -tui |
| 207 | |
Joakim Bech | 8e5c5b3 | 2018-10-25 08:18:32 +0200 | [diff] [blame] | 208 | .. _qemu_v8: |
| 209 | |
| 210 | ####### |
| 211 | QEMU v8 |
| 212 | ####### |
| 213 | The instructions here will tell how to run OP-TEE using QEMU for Armv7-A. |
| 214 | |
| 215 | Build instructions |
| 216 | ****************** |
| 217 | As long as you pick the v8 manifest, i.e., ``qemu_v8.xml`` the |
| 218 | ":ref:`get_and_build_the_solution`" tells all you need to know to build and boot |
| 219 | up QEMU v8. |
| 220 | |
| 221 | All other things (networking, GDB etc) in the v7 section above is also |
| 222 | applicable on QEMU v8 as long as you replace ``<qemu-v7-project>`` with |
| 223 | ``<qemu-v8-project>`` to get the correct paths relative to your QEMU v8 setup. |
| 224 | |
Joakim Bech | 37b5436 | 2019-03-06 10:33:46 +0100 | [diff] [blame] | 225 | .. _build/PR#340: https://github.com/OP-TEE/build/pull/340 |
| 226 | .. _Bug#4130: https://bugs.linaro.org/show_bug.cgi?id=4130#c4 |
Joakim Bech | 8e5c5b3 | 2018-10-25 08:18:32 +0200 | [diff] [blame] | 227 | .. _SLiRP: https://wiki.qemu.org/Documentation/Networking#User_Networking_.28SLIRP.29 |