1# `cloud-hypervisor` debug IO ports 2 3When running x86 guests, `cloud-hypervisor` provides different kinds of debug ports: 4- [`0x80` debug port](https://www.intel.com/content/www/us/en/support/articles/000005500/boards-and-kits.html) 5- Debug console (by default at `0xe9`). 6- Firmware debug port at `0x402`. 7 8All of them can be used to trace user-defined guest events and all of them can 9be used simultaneously. 10 11## Debug Ports Overview 12 13### `0x80` I/O port 14 15Whenever the guest write one byte between `0x0` and `0xF` on this particular 16I/O port, `cloud-hypervisor` will log and timestamp that event at the `debug` 17log level. 18 19It is up to the guest stack to decide when and what to write to the 0x80 port 20in order to signal the host about specific events and have `cloud-hypervisor` 21log it. 22 23`cloud-hypervisor` defines several debug port code ranges that should be used 24for debugging specific components of the guest software stack. When logging a 25write of one of those codes to the debug port, `cloud-hypervisor` adds a 26pre-defined string to the logs. 27 28| Code Range | Component | Log string | 29| ---------------- | ----------- | ------------ | 30| `0x00` to `0x1f` | Firmware | `Firmware` | 31| `0x20` to `0x3f` | Bootloader | `Bootloader` | 32| `0x40` to `0x5f` | Kernel | `Kernel` | 33| `0x60` to `0x7f` | Userspace | `Userspace` | 34| `0x80` to `0xff` | Custom | `Custom` | 35 36One typical use case is guest boot time measurement and tracing. By writing 37different values to the debug I/O port at different boot process steps, the 38guest will have `cloud-hypervisor` generate timestamped logs of all those steps. 39That provides a basic but convenient way of measuring not only the overall guest 40boot time but all intermediate steps as well. 41 42#### Logging 43 44Assuming parts of the guest software stack have been instrumented to use the 45`cloud-hypervisor` debug I/O port, we may want to gather the related logs. 46 47To do so we need to start `cloud-hypervisor` with the right debug level 48(`-vvv`). It is also recommended to have it log into a dedicated file in order 49to easily grep for the tracing logs (e.g. 50`--log-file /tmp/cloud-hypervisor.log`): 51 52``` 53./target/debug/cloud-hypervisor \ 54 --kernel ~/rust-hypervisor-firmware/target/target/release/hypervisor-fw \ 55 --disk path=~/hypervisor/images/focal-server-cloudimg-amd64.raw \ 56 --cpus 4 \ 57 --memory size=1024M \ 58 --rng \ 59 --log-file /tmp/ch-fw.log \ 60 -vvv 61``` 62 63After booting the guest, we then have to grep for the debug I/O port traces in 64the log file: 65 66```Shell 67$ grep "Debug I/O port" /tmp/ch-fw.log 68cloud-hypervisor: 19.762449ms: DEBUG:vmm/src/vm.rs:510 -- [Debug I/O port: Firmware code 0x0] 0.019004 seconds 69cloud-hypervisor: 403.499628ms: DEBUG:vmm/src/vm.rs:510 -- [Debug I/O port: Firmware code 0x1] 0.402744 seconds 70``` 71 72### Debug console port 73 74The debug console is inspired by QEMU and Bochs, which have a similar feature. 75By default, the I/O port `0xe9` is used. This port can be configured like a 76console. Thus, it can print to a tty, a file, or a pty, for example. 77 78### Firmware debug port 79 80The firmware debug port is also a simple port that prints all bytes written to 81it. The firmware debug port only prints to stdout. 82 83## When do I need these ports? 84 85The ports are on the one hand interesting for firmware or kernel developers, as 86they provide an easy way to print debug information from within a guest. 87Furthermore, you can patch "normal" software to measure certain events, such as 88the boot time of a guest. 89 90## Which port should I choose? 91 92The `0x80` debug port and the port of the firmware debug device are always 93available. The debug console must be activated via the command line, but 94provides more configuration options. 95 96You can use different ports for different aspect of your logging messages.