How to add a new device in QEMU source code?

17,122

Solution 1

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.

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 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.
Share:
17,122

Related videos on Youtube

San
Author by

San

Updated on June 03, 2022

Comments

  • San
    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
      osgx almost 8 years
      San, what kind of device?
  • davidA
    davidA about 6 years
    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.
  • Ciro Santilli OurBigBook.com
    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
    Onofog almost 5 years
    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 device
  • Ciro Santilli OurBigBook.com
    Ciro Santilli OurBigBook.com almost 5 years
    @Onofog thanks for this info, feel free to send a pull request!
  • user786
    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
    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
    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
    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
    user786 almost 3 years
    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.
  • Ciro Santilli OurBigBook.com
    Ciro Santilli OurBigBook.com almost 3 years
    @user786 did you git clone? Downloading the zip will likely not work.
  • user786
    user786 almost 3 years
    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-cheat
  • user786
    user786 almost 3 years
    I think this repository is joined with other repositories
  • Ciro Santilli OurBigBook.com
    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
    user786 almost 3 years
    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?
  • Ciro Santilli OurBigBook.com
    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
    user786 almost 3 years
    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?
  • Ciro Santilli OurBigBook.com
    Ciro Santilli OurBigBook.com almost 3 years
  • user786
    user786 almost 3 years
    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 this
  • Ciro Santilli OurBigBook.com
    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
    user786 almost 3 years
    Thanks for help I will check this later