How to add a new device in QEMU source code?
Asked Answered
V

2

23

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?

Vendee answered 4/2, 2015 at 6:56 Comment(1)
San, what kind of device?Tragacanth
H
21

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:

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.

Hulking answered 18/6, 2017 at 8:9 Comment(20)
Have 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.Regurgitate
@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.Hulking
In 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 deviceEmbalm
@Embalm thanks for this info, feel free to send a pull request!Hulking
@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/…Mak
@Mak 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.Hulking
@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?Mak
@Mak I don't see ./configure there. The last I link I gave does ./setup && ./build --download-dependencies qemu-buildroot && ./runHulking
I 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 section 2.1. QEMU Buildroot setup starts like This 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.Mak
@Mak did you git clone? Downloading the zip will likely not work.Hulking
can 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-cheatMak
I think this repository is joined with other repositoriesMak
@Mak submodules are automatically cloned by the build commands as needed. The commands in that section should be correct. I'm testing myself now.Hulking
Ok 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?Mak
@Mak yup, sample kernel modules is one of the many things you can do in that repo.Hulking
Where exactly is the code of kernel module that causes kernel to Oops can u give me the c file link. I want to see it. It attracts me little bit more. Can u please send the link?Mak
@Mak github.com/cirosantilli/linux-kernel-module-cheat/blob/…Hulking
This is genius how u achieved this *(int *)0=786 ur C 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 key u. If I type u on my keyboard then my kernel module should execute this *(int *)0=786 code. Requirement number 2: I need kernel module that intercepts keyboard key u and after that my system should make beeps sound. So if I type u key on my keyboard then my system should make beep sound. Is it possible. How to achieve thisMak
@Mak 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 :-)Hulking
Thanks for help I will check this laterMak
T
5

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 a TypeInfo 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's ObjectClass instance.
Tragacanth answered 19/7, 2016 at 20:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.