¿Cómo agregar un nuevo dispositivo en el código fuente de QEMU?

¿Cuál podría ser el enfoque paso a paso para emular / agregar un nuevo dispositivo en qemu utilizando el enfoque de QOM?

¿Qué y dónde podrían ser los cambios con respecto a DeviceState / BusState y otras propiedades?

    edu en el dispositivo PCI educativo en el árbol

    Es muy fácil de entender y está bien documentado, por lo que te recomiendo que lo estudies.

    Expone un dispositivo PCI mínimo, con IO básico, generación de interrupciones y DMA.

    He escrito un mínimo módulo de kernel de Linux + pruebas de userland para jugar con él en:

    Dispositivo PCI mínimo

    He reducido al mínimo el edu a una cuarta parte del tamaño en mi fork QEMU: https://github.com/cirosantilli/qemu/blob/22e7e210d6fbe54c35a5ae32450a4419df25a13b/hw/misc/lkmc_pci_min.c No DMA.

    Controlador del kernel: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/1cd55ebf53542208f7a614a856066123b93d303d/kernel_module/pci_min.c

    My Buildroot wrapper ya integra la horquilla QEMU con un submódulo, solo clona y ./run .

    Dispositivo de plataforma ARM TYPE_SYS_BUS_DEVICE

    SoC-land hornea la mayoría de los dispositivos en el silicio en lugar de PCI, aquí hay un ejemplo mínimo ejecutable:

    La bifurcación de Linux con la modificación de DTC es un submódulo del depósito de reinicio de Buildroot, así que solo clone y ./run -a arm .

    Dispositivos fuera del árbol

    Pregunté si es posible crear dispositivos fuera de árbol en: ¿Cómo crear dispositivos QEMU fuera de árbol? pero no se ve así.

    Hay algunas partes del ejemplo en la presentación 2014 de “QOM exégesis y apocalipsis” en http://events.linuxfoundation.org/sites/events/files/slides/kvmforum14-qom_0.pdf

    Creando un objeto

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

    Propiedades interiores

     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 con el código actual: http://code.metager.de/source/xref/qemu/backends/rng.c y una implementación de RNG_BACKEND http://code.metager.de/source/xref/qemu/backends/ rng-random.c )

    Estas dos páginas también pueden ser útiles: * http://wiki.qemu.org/Features/QOM * http://wiki.qemu.org/QOMConventions

    El post “API QEMU PCI esencial” por 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 ) tiene un ejemplo completo de controlador PCI habilitado para QOM.

    El QEMU Object Model (QOM) proporciona un marco para registrar tipos creables por el usuario. QOM modela buses, interfaces, dispositivos, etc. como tipos. En QOM, la información de un tipo de usuario se usa para crear su instancia de ObjectClass así como su instancia de Object. Esta información se especifica en una estructura TypeInfo ( include/qom/object.h ). Por ejemplo:

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

    dónde:

    • .name una cadena que indica el tipo de usuario.
    • .parent una cadena que especifica el Tipo del que deriva este Tipo de usuario.
    • .instance_size size de la instancia del objeto Type. Su asignación será realizada internamente por QOM. Los objetos se analizarán con más detalle en la creación de instancias de objeto de sección.
    • .class_init el gancho del constructor. Esta función será responsable de inicializar la instancia de ObjectClass del tipo.