web-dev-qa-db-ja.com

QEMUソースコードに新しいデバイスを追加するにはどうすればよいですか?

QOMアプローチを使用してqemuで新しいデバイスをエミュレート/追加するための段階的なアプローチは何でしょうか?

DeviceState/BusStateおよびその他のプロパティに関する変更はどこにありますか?

14
San

eduツリー内教育用PCIデバイス

非常に理解しやすく、十分に文書化されているので、勉強することをお勧めします。

基本的なIO、割り込み生成、およびDMAを備えた最小限のPCIデバイスを公開します。

最小限のLinuxカーネルモジュールとユーザーランドテストを作成して、次の場所で試してみました。

最小PCIデバイス

QEMUフォークのサイズの4分の1にさらにeduを最小化しました: https://github.com/cirosantilli/qemu/blob/22e7e210d6fbe54c35a5ae32450a4419df25a13b/hw/misc/lkmc_pci_min.c DMAなし。

カーネルドライバー: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/1cd55ebf53542208f7a614a856066123b93d303d/kernel_module/pci_min.c

私のBuildrootラッパーはすでにQEMUフォークをサブモジュールと統合しています。クローンを作成して./runするだけです。

ARMプラットフォームデバイスTYPE_SYS_BUS_DEVICE

SoC-landは、ほとんどのデバイスをPCIではなくシリコンでベイクします。実行可能な最小限の例を次に示します。

DTCが変更されたLinuxフォークはBuildrootラッパーリポジトリのサブモジュールであるため、クローンを作成して./run -a armするだけです。

ツリー外のデバイス

ツリー外のデバイスを作成できるかどうかを尋ねました: ツリー外のQEMUデバイスを作成する方法は? しかし、そのようには見えません。

「QOM聖書釈義と黙示録」2014年のプレゼンテーションの例の一部があります http://events.linuxfoundation.org/sites/events/files/slides/kvmforum14-qom_0.pdf

オブジェクトの作成

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

内部プロパティ

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

(実際のコードと比較してください: http://code.metager.de/source/xref/qemu/backends/rng.c およびRNG_BACKENDの1つの実装 http://code.metager .de/source/xref/qemu/backends/rng-random.c

これらの2つのページも役立つ場合があります:* http://wiki.qemu.org/Features/QOM * http://wiki.qemu.org/QOMConventions

SiroMugabiによる投稿「EssentialQEMUPCI API」: http://nairobi-embedded.org/001_qemu_pci_device_essentials.htmlhttp://web.archive.org/web/20151116022950 /http://nairobi-embedded.org/001_qemu_pci_device_essentials.html )には、QOM対応のPCIドライバーの完全な例があります。

QEMUオブジェクトモデル(QOM)は、ユーザーが作成可能なタイプを登録するためのフレームワークを提供します。 QOMは、バス、インターフェイス、デバイスなどをタイプとしてモデル化します。 QOMでは、ユーザータイプごとの情報を使用して、そのObjectClassインスタンスとそのオブジェクトインスタンスを作成します。この情報は、TypeInfo構造体(include/qom/object.h)。例えば:

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

どこ:

  • .nameユーザータイプを示す文字列。
  • .parentこのユーザータイプの派生元のタイプを指定する文字列。
  • .instance_sizeタイプのオブジェクトインスタンスのサイズ。その割り当ては、QOMによって内部的に実行されます。オブジェクトについては、セクションオブジェクトのインスタンス化で詳しく説明します。
  • .class_initコンストラクタフック。この関数は、タイプのObjectClassインスタンスの初期化を担当します。
4
osgx