qemu与spice通信

Qemu内部维护了一个全局的设备列表,所有Qemu内部实现的虚拟设备结构对象如显卡、声卡等都注册到该全局设备列表中。Qemu的main函数执行以前,该全局设备列表已经初始化完成,因此在Qmeu的main函数执行过程中是找不到设备列表初始化的语句的,该特性必须由gcc编译器支持。Qemu的main函数负责所有注册到全局设备列表中的设备的初始化工作,即调用这些设备对象的init函数。
虚拟设备需要实现对应的物理设备所支持的所有基本功能。
以虚拟显卡为例,虚拟设备必须实现标准VGA支持的所有I/0端口、显存、ROM等,所有这些工作都必须在init中完成,以保证设备能正常工作。
虚拟显卡产生视频数据后,libspice需要主动调用get_command函数去获取数据,然后在libspice中进行相关的处理后发送到client。
音频处理则是在虚拟声卡的实现中 直接调用libspice导出的api,将音频数据发送到client这与音频数据处理的实现方式有关系, 因此Qemu不需要为libspice开放接口。
音频处理API接口如下:
spice_server_playback_put_samples
spice_server_record_get_samples
spice与qemu主要通信接口
SpiceCoreInterface:    Spice与Qemu内部交互用的接口
QXLInterface:          显示数据交互接口
SpiceKbdInstance:      键盘输入交互接口
SpiceMouseInterface:   鼠标输入交互接口
SpicePlaybackInterface:音频播放交互接口
SpiceRecordInterface:  音频录制交互接口
SpiceBaseInterface 基本的后端接口
struct SpiceBaseInterface {
    const char *type;
    const char *description;
    uint32_t major_version;
    uint32_t minor_version;
};

核心接口SpiceCoreInterface Timer和Watch的 2组函数, 其具体功能 由Qemu实现供libspice调用。这两组函数的作用分别是用来 在Qemu中设置定时器和维护网络事件
struct SpiceCoreInterface {
    SpiceBaseInterface base;

    //定时器
    SpiceTimer *(*timer_add)(SpiceTimerFunc func, void *opaque);
    void (*timer_start)(SpiceTimer *timer, uint32_t ms);
    void (*timer_cancel)(SpiceTimer *timer);
    void (*timer_remove)(SpiceTimer *timer);

    //file ID 监听器
    SpiceWatch *(*watch_add)(int fd, int event_mask, SpiceWatchFunc func, void *opaque);
    void (*watch_update_mask)(SpiceWatch *watch, int event_mask);
    void (*watch_remove)(SpiceWatch *watch);
    void (*channel_event)(int event, SpiceChannelEventInfo *info);
};

比如网络watch监听器,red_accept为回调处理函数,监听listen_socket的SPICE_WATCH_EVENT_READ可读事件。
static void reds_init_net()
{
    if (spice_port != -1) {
        reds->listen_socket = reds_init_socket();
        reds->listen_watch = core->watch_add(reds->listen_socket,SPICE_WATCH_EVENT_READ,reds_accept, NULL);
        if (reds->listen_watch == NULL) {
            red_error("set fd handle failed");
        }
    }
}

显示处理的backend接口: 结构中的函数指针由Qemu实现,并在调用spice_server_add_interface时初始化并传递给libspice。所有函数均与视频处理紧密相关,最重要的命令:get_command,用来从虚拟显卡设备中获取显示处理命令。
struct QXLInterface {
    SpiceBaseInterface base;
    void (*attache_worker)(QXLInstance *qin, QXLWorker *qxl_worker);
    void (*set_compression_level)(QXLInstance *qin, int level);
    void (*set_mm_time)(QXLInstance *qin, uint32_t mm_time);
    void (*get_init_info)(QXLInstance *qin, QXLDevInitInfo *info);
    int (*get_command)(QXLInstance *qin, struct QXLCommandExt *cmd);
    int (*req_cmd_notification)(QXLInstance *qin);
    void (*release_resource)(QXLInstance *qin, struct QXLReleaseInfoExt release_info);
    int (*get_cursor_command)(QXLInstance *qin, struct QXLCommandExt *cmd);
    int (*req_cursor_notification)(QXLInstance *qin);
    void (*notify_update)(QXLInstance *qin, uint32_t update_id);
    int (*flush_resources)(QXLInstance *qin);
};

显示处理的 fontend接口: 结构中的函数指针由libspice实现, 一部分就是用来控制线程运转的命令,另一部分则是内存数据交互、图像处理相关的控制接口。
struct QXLWorker {
    uint32_t minor_version;
    uint32_t major_version;
    void (*wakeup)(QXLWorker *worker);
    void (*oom)(QXLWorker *worker);
    void (*start)(QXLWorker *worker);
    void (*stop)(QXLWorker *worker);

    void (*update_area)(QXLWorker *qxl_worker, uint32_t surface_id,struct QXLRect *area, struct QXLRect *dirty_rects,uint32_t num_dirty_rects, uint32_t clear_dirty_region);
    void (*add_memslot)(QXLWorker *worker, QXLDevMemSlot *slot);
    void (*del_memslot)(QXLWorker *worker, uint32_t slot_group_id, uint32_t slot_id);
    void (*reset_memslots)(QXLWorker *worker);
    void (*destroy_surfaces)(QXLWorker *worker);
    void (*destroy_primary_surface)(QXLWorker *worker, uint32_t surface_id);
    void (*create_primary_surface)(QXLWorker *worker, uint32_t surface_id,QXLDevSurfaceCreate *surface);
    void (*reset_image_cache)(QXLWorker *worker);
    void (*reset_cursor)(QXLWorker *worker);
    void (*destroy_surface_wait)(QXLWorker *worker, uint32_t surface_id);
    void (*loadvm_commands)(QXLWorker *worker, struct QXLCommandExt *ext, uint32_t count);
};

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值