Comment ajouter un nouveau périphérique dans le code source QEMU?

quelle pourrait être l'approche par étapes pour émuler/ajouter un nouveau dispositif dans qemu en utilisant l'approche QOM?

quels et où pourraient être les changements concernant DeviceState/BusState et d'autres propriétés?

7

2 réponses

edu dans l'arborescence d'enseignement PCI device

C'est très facile à comprendre et bien documenté, donc je vous recommande de l'étudier.

il expose un dispositif PCI minimal, avec IO de base, génération d'interruption, et DMA.

j'ai écrit un module minimal du noyau Linux + des tests userland pour jouer avec:

Minimal PCI device

j'ai encore réduit edu à un quart de la taille sur ma fourchette QEMU: https://github.com/cirosantilli/qemu/blob/22e7e210d6fbe54c35a5ae32450a4419df25a13b/hw/misc/lkmc_pci_min.c No DMA.

pilote de noyau: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/1cd55ebf53542208f7a614a856066123b93d303d/kernel_module/pci_min.c

mon wrapper Buildroot intègre déjà la fourche QEMU avec un sous-module, il suffit de cloner et ./run .

BRAS dispositif de plate-forme TYPE_SYS_BUS_DEVICE

SoC-land fabrique la plupart des appareils dans le silicium au lieu de PCI, ici est un exemple de fonctionnement minimal:

la fourche Linux avec la modification DTC est un sous-module du repo Buildroot wrapper, donc il suffit de cloner et ./run -a arm .

Hors de l'arborescence de périphériques

j'ai demandé s'il est possible de créer des périphériques out-of-tree à: comment créer des périphériques out-of-tree QEMU? mais ça n'y ressemble pas.

7

il y a quelques parties de l'exemple dans" Qom exégèse et apocalypse "2014 Présentation à http://events.linuxfoundation.org/sites/events/files/slides/kvmforum14-qom_0.pdf

créer un objet

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);

propriétés intérieures

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,
};

(comparer avec le code réel: http://code.metager.de/source/xref/qemu/backends/rng.c et une mise en œuvre de RNG_BACKEND http://code.metager.de/source/xref/qemu/backends/rng-random.c )

ces deux pages peuvent être utiles aussi: * http://wiki.qemu.org/Features/QOM * http://wiki.qemu.org/QOMConventions

l'après "L'Essentiel QEMU PCI API" par 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 ) contient un exemple complet de pilote PCI activé par QOM.

le modèle D'objet QEMU (QOM) fournit un cadre pour enregistrer les Types créables par l'utilisateur. QOM modèles de bus, interfaces, périphériques, etc comme des types. Dans QOM, l'information par type d'utilisateur est utilisée pour créer son instance ObjectClass ainsi que son instance objet. Cette information est spécifiée dans une structure TypeInfo ( include/qom/object.h ). Par exemple:

/* 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,
};

où:

  • .name chaîne de caractères qui indique le type d'utilisateur.
  • .parent chaîne de caractères qui spécifie le Type dont ce type d'utilisateur provient.
  • .instance_size taille de l'instance de L'objet du Type. Sa répartition sera effectuée en interne par QOM. Les objets seront discutés plus en détail dans la section instanciation des objets.
  • .class_init le crochet du constructeur. Cette fonction sera chargée d'initialiser l'instance de Type ObjectClass .
4
répondu osgx 2016-07-19 20:31:51