21

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?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
San
  • 905
  • 3
  • 16
  • 33

2 Answers2

20

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.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • Have you had any experience with [uio](https://www.kernel.org/doc/html/v4.12/driver-api/uio-howto.html) 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. – davidA Mar 15 '18 at 03:03
  • @meowsqueak I [was considering](https://github.com/cirosantilli/linux-kernel-module-cheat/blob/e8f09a76e6b40f61f4b445a40eb28eb4f36a7392/kernel_module/user/uio_read.c) 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: https://www.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. – Ciro Santilli OurBigBook.com Mar 15 '18 at 09:06
  • 1
    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](https://github.com/qemu/qemu/blob/master/hw/misc/edu.c) – Onofog Jun 24 '19 at 19:44
  • @Onofog thanks for this info, feel free to send a pull request! – Ciro Santilli OurBigBook.com Jun 24 '19 at 20:30
  • 1
    @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 https://github.com/cirosantilli/linux-kernel-module-cheat/tree/762bb78d89d1359c01a7ecee37e3f8132a48c1ce#qemu-buildroot-setup – user786 Jul 14 '21 at 12:43
  • @user786 hi, not sure which version you are at, this answer points to https://github.com/cirosantilli/linux-kernel-module-cheat/tree/6788a577c394a2fc512d8f3df0806d84dc09f355 but there is no configure in that version, and neither is there one on current master: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/38eb67ad2ec46b58dbc701073ce0e980fad7788b Just use this section as a starting point: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/38eb67ad2ec46b58dbc701073ce0e980fad7788b#qemu-buildroot-setup and you should be fine. – Ciro Santilli OurBigBook.com Jul 14 '21 at 17:42
  • @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? – user786 Jul 15 '21 at 02:26
  • @user786 I don't see `./configure` there. The last I link I gave does `./setup && ./build --download-dependencies qemu-buildroot && ./run` – Ciro Santilli OurBigBook.com Jul 15 '21 at 07:49
  • 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.` – user786 Jul 15 '21 at 08:05
  • @user786 did you git clone? Downloading the zip will likely not work. – Ciro Santilli OurBigBook.com Jul 15 '21 at 08:13
  • 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 Jul 15 '21 at 08:22
  • I think this repository is joined with other repositories – user786 Jul 15 '21 at 08:23
  • @user786 submodules are automatically cloned by the build commands as needed. The commands in that section should be correct. I'm testing myself now. – Ciro Santilli OurBigBook.com Jul 15 '21 at 08:45
  • 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? – user786 Jul 15 '21 at 12:19
  • @user786 yup, sample kernel modules is one of the many things you can do in that repo. – Ciro Santilli OurBigBook.com Jul 15 '21 at 12:59
  • 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? – user786 Jul 15 '21 at 13:46
  • @user786 https://github.com/cirosantilli/linux-kernel-module-cheat/blob/38eb67ad2ec46b58dbc701073ce0e980fad7788b/kernel_modules/oops.c#L9 – Ciro Santilli OurBigBook.com Jul 15 '21 at 13:52
  • 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 – user786 Jul 15 '21 at 14:27
  • @user786 have a look at https://cirosantilli.com/linux-kernel-module-cheat/#irq-ko to detect keyboard hits. For beeper, I don't know, gotta google + grep a bit :-) – Ciro Santilli OurBigBook.com Jul 15 '21 at 14:31
  • Thanks for help I will check this later – user786 Jul 15 '21 at 16:04
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.
osgx
  • 90,338
  • 53
  • 357
  • 513