What could be the step wise approach to emulate/add a new device in qemu
using QOM approach?
What and where could be the changes with respect to DeviceState/BusState and other properties?
What could be the step wise approach to emulate/add a new device in qemu
using QOM approach?
What and where could be the changes with respect to DeviceState/BusState and other properties?
edu
in-tree educational PCI device
It is very easy to understand and well documented, so I recommend that you study it.
It exposes a minimal PCI device, with basic IO, interrupt generation, and DMA.
I've written a minimal Linux kernel module + userland tests to play with it at:
Minimal PCI device
I've minimized edu even further to a quarter of the size on my QEMU fork: https://github.com/cirosantilli/qemu/blob/22e7e210d6fbe54c35a5ae32450a4419df25a13b/hw/misc/lkmc_pci_min.c No DMA.
Kernel driver: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/1cd55ebf53542208f7a614a856066123b93d303d/kernel_module/pci_min.c
My Buildroot wrapper already integrates the QEMU fork with a submodule, just clone and ./run
.
ARM platform device TYPE_SYS_BUS_DEVICE
SoC-land bakes most devices in the silicon instead of PCI, here is a minimal runnable example:
-M versatilepb
: https://github.com/cirosantilli/qemu/blob/144ea94d710c666babd06ed733007377e132ed4a/hw/arm/versatilepb.c#L302 Uses sysbus_create_simple
, which expects a device of type TYPE_SYS_BUS_DEVICE
.versatilepb.c
compatible
matches the platform_driver.name
in the kernel module, and informs the kernel which module will handle this device.-dtb
The Linux fork with the DTC modification is a submodule of the Buildroot wrapper repo, so just clone and ./run -a arm
.
Out-of-tree devices
I asked if it is possible to make out-of-tree devices at: How to create out-of-tree QEMU devices? but it does not look like it.
There are some parts of example in "QOM exegesis and apocalypse" 2014 presentation at http://events.linuxfoundation.org/sites/events/files/slides/kvmforum14-qom_0.pdf
Creating an object
Object *o = object_new(TYPE_RNG_BACKEND_RANDOM); object_property_set_str(o, "filename", "/dev/random", NULL); object_property_set_bool(o, "opened", "true", NULL); object_property_add_child(container_get("/somewhere"), "my-rng", o, NULL); object_unref(o);
Inside properties
static bool rng_get_opened(Object *obj, Error **errp) { RngBackend *s = RNG_BACKEND(obj); return s->opened; } static void rng_set_opened(Object *obj, bool value, Error **errp) { RngBackend *s = RNG_BACKEND(obj); RngBackendClass *k = RNG_BACKEND_GET_CLASS(s); ... if (k->opened) { k->opened(s, errp) } } static void rng_backend_init(Object *obj) { object_property_add_bool(obj, "opened", rng_get_opened, rng_set_opened, NULL); } static const TypeInfo rng_backend_info = { .name = TYPE_RNG_BACKEND, .parent = TYPE_OBJECT, .instance_size = sizeof(RngBackend), .instance_init = rng_backend_init, .class_size = sizeof(RngBackendClass), .abstract = true, };
(compare with actual code: http://code.metager.de/source/xref/qemu/backends/rng.c and one implementation of RNG_BACKEND http://code.metager.de/source/xref/qemu/backends/rng-random.c)
These two pages may be useful too: * http://wiki.qemu.org/Features/QOM * http://wiki.qemu.org/QOMConventions
The post "Essential QEMU PCI API" by Siro Mugabi: http://nairobi-embedded.org/001_qemu_pci_device_essentials.html (http://web.archive.org/web/20151116022950/http://nairobi-embedded.org/001_qemu_pci_device_essentials.html) has complete example of QOM-enabled PCI driver.
The QEMU Object Model (QOM) provides a framework for registering user creatable Types. QOM models buses, interfaces, devices, etc as types. In QOM, information by a user Type is used to create its
ObjectClass
instance as well as its Object instance. This information is specified in aTypeInfo
structure (include/qom/object.h
). For example:/* hw/misc/pci-testdev.c */ static const TypeInfo pci_testdev_info = { .name = TYPE_PCI_TEST_DEV, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCITestDevState), .class_init = pci_testdev_class_init, };
where:
.name
a string that indicates the user Type..parent
a string that specifies the Type from which this user Type derives from..instance_size
size of the Type's Object instance. Its allocation will be performed internally by QOM. Objects will be discussed in more detail in Section Object Instantiation..class_init
the constructor hook. This function will be responsible for initializing the Type'sObjectClass
instance.