How to add a new device in QEMU source code?
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
- https://github.com/qemu/qemu/blob/v2.7.0/hw/misc/edu.c
- https://github.com/qemu/qemu/blob/v2.7.0/docs/specs/edu.txt
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:
- https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/rootfs_overlay/pci.sh
- https://github.com/cirosantilli/linux-kernel-module-cheat/blob/6788a577c394a2fc512d8f3df0806d84dc09f355/kernel_module/pci.c
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.