How to add a new device in QEMU source code?
Solution 1
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.
Solution 2
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.
Related videos on Youtube
San
Updated on June 03, 2022Comments
-
San almost 2 years
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?
-
osgx almost 8 yearsSan, what kind of device?
-
-
davidA about 6 yearsHave you had any experience with uio and the edu or your own derived driver? I'm not able to get uio_pci_generic to enumerate addressing regions. It recognises and binds to the edu device but there is no
/sys/class/uio/uio0/map
directory. -
Ciro Santilli OurBigBook.com about 6 years@meowsqueak I was considering playing around with UIO but gave up halfway. Send me a pull request if you get anything working. Also it appears that VFIO is the new shinny thing: kernel.org/doc/Documentation/vfio.txt although there are no examples to be found anywhere, you so you might want to focus on that instead.
-
Onofog almost 5 yearsIn the minimal examples here, the TypeInfo struct does not include the .interfaces field. To pass an assert in the parent class, they can be amended as in line 431 from the latest example edu.c device
-
Ciro Santilli OurBigBook.com almost 5 years@Onofog thanks for this info, feel free to send a pull request!
-
user786 almost 3 years@CiroSantilli新疆再教育营六四事件法轮功郝海东 I am looking at ur github document on ` test low level system components by using system simulators.` I ran this command but there is no ./configure file
cd linux-kernel-module-cheat ./configure && \ ./build-qemu && ./build-buildroot &&./run && \:;
did u changed anything. how do I check this now? can u please explain github.com/cirosantilli/linux-kernel-module-cheat/tree/… -
Ciro Santilli OurBigBook.com almost 3 years@user786 hi, not sure which version you are at, this answer points to github.com/cirosantilli/linux-kernel-module-cheat/tree/… but there is no configure in that version, and neither is there one on current master: github.com/cirosantilli/linux-kernel-module-cheat/tree/… Just use this section as a starting point: github.com/cirosantilli/linux-kernel-module-cheat/tree/… and you should be fine.
-
user786 almost 3 years@CiroSantilli新疆再教育营六四事件法轮功郝海东 I am referring to first command on the page in ur comment. When u start qemu
cd linux-kernel-module-cheat
directory after going in that directory.cd linux-kernel-module-cheat/ it's on the first chapter of ur document. Or can u please let me know how to start using ur repository. What is the first command I should run after I download ur repository before downloading qemu. Can u please tell me this? -
Ciro Santilli OurBigBook.com almost 3 years@user786 I don't see
./configure
there. The last I link I gave does./setup && ./build --download-dependencies qemu-buildroot && ./run
-
user786 almost 3 yearsI got this error
fatal: not a git repository (or any of the parent directories): .git
after message:update-initramfs: Generating /boot/initrd.img-5.12.6
the command is in section2.1. QEMU Buildroot setup
starts likeThis is the best setup if you are on Ubuntu. We tend to test this repo the most on the latest Ubuntu, and on the latest Ubuntu LTS.
-
Ciro Santilli OurBigBook.com almost 3 years@user786 did you git clone? Downloading the zip will likely not work.
-
user786 almost 3 yearscan u please tell me what exact command I have to run to clone it. I tried. but submodules directory and many other files and directories not included into the downloaded tar using clone. Before I looked the command of clone in ur doc which is given as git clone
git clone https://github.com/cirosantilli/linux-kernel-module-cheat
-
user786 almost 3 yearsI think this repository is joined with other repositories
-
Ciro Santilli OurBigBook.com almost 3 years@user786 submodules are automatically cloned by the build commands as needed. The commands in that section should be correct. I'm testing myself now.
-
user786 almost 3 yearsOk just need to know how this exactly work. So basically I understood is there are kernel modules that do different things like causing
kernel to Oops
etc. Am I getting it correctly? Can u tell me my understanding of ur repository is correct? -
Ciro Santilli OurBigBook.com almost 3 years@user786 yup, sample kernel modules is one of the many things you can do in that repo.
-
user786 almost 3 yearsWhere exactly is the code of kernel module that causes
kernel to Oops
can u give me thec
file link. I want to see it. It attracts me little bit more. Can u please send the link? -
Ciro Santilli OurBigBook.com almost 3 years
-
user786 almost 3 yearsThis is genius how u achieved this
*(int *)0=786
urC programming language must be very good
basically if I may explain what I am trying to do. This is my requirement 1: i need kernel module that intercepts keyboard's specific keyu
. If I typeu
on my keyboard then my kernel module should execute this*(int *)0=786
code. Requirement number 2: I need kernel module that intercepts keyboard keyu
and after that my system should make beeps sound. So if I typeu
key on my keyboard then my system should make beep sound. Is it possible. How to achieve this -
Ciro Santilli OurBigBook.com almost 3 years@user786 have a look at cirosantilli.com/linux-kernel-module-cheat/#irq-ko to detect keyboard hits. For beeper, I don't know, gotta google + grep a bit :-)
-
user786 almost 3 yearsThanks for help I will check this later