Skip to content
Table of contents

QEMU 外设建模模板

2 min read ··· views #qemu / #设备模型 / #模拟器

QEMU 自定义外设模板

此模板为在 QEMU 中开发外设提供了指南,其中包含详细的解释和代码注释。


1. 引入必要的头文件

这些头文件是编写大多数 QEMU 设备模型所必需的。

#include "qemu/osdep.h"             // OS 兼容层
#include "hw/irq.h"                 // 中断请求 (IRQ) 处理
#include "hw/qdev-properties.h"     // QEMU 设备属性管理
#include "migration/vmstate.h"      // 虚拟机迁移支持
#include "qemu/log.h"               // QEMU 日志功能
#include "qemu/module.h"            // QEMU 模块初始化
c

2. 定义设备状态结构体

定义一个结构体来保存自定义设备的内部状态,包括设备所需的寄存器和状态标志。

typedef struct CustomDeviceState {
    SysBusDevice parent_obj;   // 系统总线设备的基础结构
    uint32_t reg1;             // 示例寄存器 1
    uint32_t reg2;             // 示例寄存器 2
    uint64_t tick_offset;      // 时间或时钟偏移
    bool enable;               // 设备启用标志
    QEMUTimer *timer;          // 定时器,用于计划事件
    qemu_irq irq;              // 中断请求
    MemoryRegion iomem;        // 内存映射 I/O 区域
} CustomDeviceState;
c

3. 设备初始化与重置

  • reset():重置设备的内部状态和寄存器。
  • init():初始化设备,包括内存和中断连接。

4. 实现读写函数

这些函数定义了设备如何处理对寄存器的读写请求。


5. 定义 MemoryRegion 操作

此部分将读写函数绑定到设备的内存区域。

static const MemoryRegionOps custom_device_ops = {
    .read = custom_device_read,    // 绑定读取函数
    .write = custom_device_write,  // 绑定写入函数
    .endianness = DEVICE_NATIVE_ENDIAN,  // 使用本地字节序
};
c

6. 支持虚拟机迁移(可选)

如果设备需要支持虚拟机迁移,开发者需要指明应被保存和恢复的字段。

static const VMStateDescription vmstate_custom_device = {
    .name = "custom_device",       // VM 状态名称
    .version_id = 1,               // 状态版本 ID
    .minimum_version_id = 1,       // 最小兼容版本 ID
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(reg1, CustomDeviceState),  // 保存/恢复 reg1
        VMSTATE_UINT32(reg2, CustomDeviceState),  // 保存/恢复 reg2
        VMSTATE_END_OF_LIST()                     // 状态字段列表结束
    }
};
c

7. 实现并注册设备

此函数实现设备的具体逻辑:初始化定时器并连接中断。


遵循此模板,开发者即可在 QEMU 中实现支持 MMIO、中断以及可选迁移功能的自定义外设,也可以根据具体的设备需求进行修改。