Some time ago, I asked a similar question, "How to connect GPIO in QEMU-emulated machine to an object in host?" and after some work, I have found a not perfect but satisfactory solution.
However, now we have virtio that supports GPIO, and it would be good to use that solution instead of a modified mpc8xxx driver. That previous solution was not perfect and difficult to maintain (I have only ported it to Buildroot 2021.02 and stopped further maintenance).
Unfortunately, I don't see any implementation of host-side virtio-user-gpio that I could use to connect GUI to a machine emulated in QEMU.
Is there any library (preferably with Python bindings) that could facilitate this task? Should I start from scratch, implementing the virtio protocol for the GPIO device as defined in the specification?
Finally, after almost a year, I have found an answer to my question. Indeed, the right solution was based on Rust implementation of vhost-user-gpio. I have created my own fork, with the solution in the branch gpio-python.
I have modified the implementation of the MockGpioDevice, making it connect to the JSON RPC server using the simple HTTP transport:
The individual functions handling changes in the state of GPIOs do the RPC calls. For example the reading and writing of the GPIO pin is implemented as follows:
The JSON RPC server is implemented in Python using tinyrpc. It is connected to the Gtk GUI adapted from my old solution.
The corresponding read and write pin implementations are very simple.
The field
val
is modified by the send_change function in GUI:That function also supports handling the GPIO-generated interrupts with the wait_for_interrupt function.
The corresponding function in the vhost-device-gpio is the following:
For testing, I first started the GUI by running
python3 gui3.py
in the virtual environment with installed:tinyrpc
,gevent
,werkzeug
, andpgi
. Then I started the vhost-device-gpio:The LD_LIBRARY_PATH must be set because, in my Debian/testing machine, an old libgpiod is used. Therefore, I had to compile the new version in
/home/emb/libgpiod-2.1
. Of course, thevhost-device-gpio
also needed to be built specially:When GUI and vhost-device-gpio were started, I could run the QEMU with a guest OS connecting to my emulated GPIO. I have used Linux built for
qemu-aarch64-virt
platform with Buildroot 2023.11.1 for that purpose.Of course, I had to enable
CONFIG_GPIO_VIRTIO=m
in the Linux kernel configuration. To emulate GPIO interrupts, the QEMU had to be patched, as described here.The QEMU was started with the following additional arguments:
After the emulated machine starts, it is possible to load the driver:
modprobe gpio-virtio
. Then it is possible to test interrupts withgpiomon 0 12
, read pins withgpioget 0 4
or write them withgpioset 0 24
(of course you may change the pin numbers).The described solution is only a proof of the concept. Error detection and handling are almost non-existent. Also, stopping the emulation when the guest waits for the interrupt may be difficult. However, I hope this may be a good starting point for further development.