QEMU源码全解析38 —— Machine(8)

这篇具有很好参考价值的文章主要介绍了QEMU源码全解析38 —— Machine(8)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

接前一篇文章:QEMU源码全解析37 —— Machine(7)

本文内容参考:

《趣谈Linux操作系统》 —— 刘超,极客时间

《QEMU/KVM》源码解析与应用 —— 李强,机械工业出版社

特此致谢!

上一回经过了重重周折,终于找到了MACHINE的定义所在:

OBJECT_DECLARE_TYPE(MachineState, MachineClass, MACHINE)

本回就详细解析一下这段代码。别看代码只有一行,内容还是蛮多的。

OBJECT_DECLARE_TYPE是一个宏,在include/qom/object.h中定义,代码如下:

/**
 * OBJECT_DECLARE_TYPE:
 * @InstanceType: instance struct name
 * @ClassType: class struct name
 * @MODULE_OBJ_NAME: the object name in uppercase with underscore separators
 *
 * This macro is typically used in a header file, and will:
 *
 *   - create the typedefs for the object and class structs
 *   - register the type for use with g_autoptr
 *   - provide three standard type cast functions
 *
 * The object struct and class struct need to be declared manually.
 */
#define OBJECT_DECLARE_TYPE(InstanceType, ClassType, MODULE_OBJ_NAME) \
    typedef struct InstanceType InstanceType; \
    typedef struct ClassType ClassType; \
    \
    G_DEFINE_AUTOPTR_CLEANUP_FUNC(InstanceType, object_unref) \
    \
    DECLARE_OBJ_CHECKERS(InstanceType, ClassType, \
                         MODULE_OBJ_NAME, TYPE_##MODULE_OBJ_NAME)

这里边又涉及到两个宏:G_DEFINE_AUTOPTR_CLEANUP_FUNC和DECLARE_OBJ_CHECKERS。重点关注后一个。

DECLARE_OBJ_CHECKERS宏实际上就在OBJECT_DECLARE_TYPE宏的上边,代码如下:

/**
 * DECLARE_OBJ_CHECKERS:
 * @InstanceType: instance struct name
 * @ClassType: class struct name
 * @OBJ_NAME: the object name in uppercase with underscore separators
 * @TYPENAME: type name
 *
 * Direct usage of this macro should be avoided, and the complete
 * OBJECT_DECLARE_TYPE macro is recommended instead.
 *
 * This macro will provide the three standard type cast functions for a
 * QOM type.
 */
#define DECLARE_OBJ_CHECKERS(InstanceType, ClassType, OBJ_NAME, TYPENAME) \
    DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
    \
    DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME)

这里边又包含了DECLARE_INSTANCE_CHECKER和DECLARE_CLASS_CHECKERS两个宏定义。打破砂锅问到底,看看这两个宏的代码,实际上就在DECLARE_OBJ_CHECKERS宏的上边。

/**
 * DECLARE_INSTANCE_CHECKER:
 * @InstanceType: instance struct name
 * @OBJ_NAME: the object name in uppercase with underscore separators
 * @TYPENAME: type name
 *
 * Direct usage of this macro should be avoided, and the complete
 * OBJECT_DECLARE_TYPE macro is recommended instead.
 *
 * This macro will provide the instance type cast functions for a
 * QOM type.
 */
#define DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
    static inline G_GNUC_UNUSED InstanceType * \
    OBJ_NAME(const void *obj) \
    { return OBJECT_CHECK(InstanceType, obj, TYPENAME); }
/**
 * DECLARE_CLASS_CHECKERS:
 * @ClassType: class struct name
 * @OBJ_NAME: the object name in uppercase with underscore separators
 * @TYPENAME: type name
 *
 * Direct usage of this macro should be avoided, and the complete
 * OBJECT_DECLARE_TYPE macro is recommended instead.
 *
 * This macro will provide the class type cast functions for a
 * QOM type.
 */
#define DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME) \
    static inline G_GNUC_UNUSED ClassType * \
    OBJ_NAME##_GET_CLASS(const void *obj) \
    { return OBJECT_GET_CLASS(ClassType, obj, TYPENAME); } \
    \
    static inline G_GNUC_UNUSED ClassType * \
    OBJ_NAME##_CLASS(const void *klass) \
    { return OBJECT_CLASS_CHECK(ClassType, klass, TYPENAME); }

好了,现在各个宏定义基本都已经给出了(G_DEFINE_AUTOPTR_CLEANUP_FUNC暂时不展开),开始逐层展开,到底看看完全展开之后是个内容。

第1层:

#define OBJECT_DECLARE_TYPE(InstanceType, ClassType, MODULE_OBJ_NAME) \
    typedef struct InstanceType InstanceType; \
    typedef struct ClassType ClassType; \
    \
    G_DEFINE_AUTOPTR_CLEANUP_FUNC(InstanceType, object_unref) \
    \
    DECLARE_OBJ_CHECKERS(InstanceType, ClassType, \
                         MODULE_OBJ_NAME, TYPE_##MODULE_OBJ_NAME)

代入

OBJECT_DECLARE_TYPE(MachineState, MachineClass, MACHINE)

中的实际值:InstanceType <-> MachineState,ClassType <-> MachineClass,MODULE_OBJ_NAME <-> MACHINE,得到:

    typedef struct MachineState MachineState;
    typedef struct MachineClass MachineClass;

    G_DEFINE_AUTOPTR_CLEANUP_FUNC(MachineState, object_unref)

    DECLARE_OBJ_CHECKERS(MachineState, MachineClass, \
                         MACHINE, TYPE_MACHINE)

第2层:

#define DECLARE_OBJ_CHECKERS(InstanceType, ClassType, OBJ_NAME, TYPENAME) \
    DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
    \
    DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME)

代入

DECLARE_OBJ_CHECKERS(MachineState, MachineClass, \
                         MACHINE, TYPE_MACHINE)

中的实际值:InstanceType <-> MachineState,ClassType <-> MachineClass,OBJ_NAME <-> MACHINE,TYPENAME <-> TYPE_MACHINE,得到:

    DECLARE_INSTANCE_CHECKER(MachineState, MACHINE, TYPE_MACHINE) 

    DECLARE_CLASS_CHECKERS(MachineClass, MACHINE, TYPE_MACHINE)

第3层:

#define DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
    static inline G_GNUC_UNUSED InstanceType * \
    OBJ_NAME(const void *obj) \
    { return OBJECT_CHECK(InstanceType, obj, TYPENAME); }

#define DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME) \
    static inline G_GNUC_UNUSED ClassType * \
    OBJ_NAME##_GET_CLASS(const void *obj) \
    { return OBJECT_GET_CLASS(ClassType, obj, TYPENAME); } \
    \
    static inline G_GNUC_UNUSED ClassType * \
    OBJ_NAME##_CLASS(const void *klass) \
    { return OBJECT_CLASS_CHECK(ClassType, klass, TYPENAME); }

分别代入

    DECLARE_INSTANCE_CHECKER(MachineState, MACHINE, TYPE_MACHINE) 

    DECLARE_CLASS_CHECKERS(MachineClass, MACHINE, TYPE_MACHINE)

中的实际值:InstanceType <-> MachineState,OBJ_NAME <-> MACHINE,TYPENAME <-> TYPE_MACHINE;ClassType <-> MachineClass,OBJ_NAME <-> MACHINE,TYPENAME <-> TYPE_MACHINE分别得到:

    static inline G_GNUC_UNUSED MachineState * 
    MACHINE(const void *obj)
    { return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE); }
    static inline G_GNUC_UNUSED MachineClass * 
    MACHINE_GET_CLASS(const void *obj) 
    { return OBJECT_GET_CLASS(MachineClass, obj, TYPE_MACHINE); } 

    static inline G_GNUC_UNUSED MachineClass * 
    MACHINE_CLASS(const void *klass) 
    { return OBJECT_CLASS_CHECK(MachineClass, klass, TYPE_MACHINE); }

与上面综合,得到:

    typedef struct MachineState MachineState;
    typedef struct MachineClass MachineClass;

    G_DEFINE_AUTOPTR_CLEANUP_FUNC(MachineState, object_unref)

    static inline G_GNUC_UNUSED MachineState * 
    MACHINE(const void *obj)
    { return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE); }

    static inline G_GNUC_UNUSED MachineClass * 
    MACHINE_GET_CLASS(const void *obj) 
    { return OBJECT_GET_CLASS(MachineClass, obj, TYPE_MACHINE); } 

    static inline G_GNUC_UNUSED MachineClass * 
    MACHINE_CLASS(const void *klass) 
    { return OBJECT_CLASS_CHECK(MachineClass, klass, TYPE_MACHINE); }

整理成更好理解的格式:

    typedef struct MachineState MachineState;
    typedef struct MachineClass MachineClass;

    G_DEFINE_AUTOPTR_CLEANUP_FUNC(MachineState, object_unref)

    static inline G_GNUC_UNUSED MachineState *MACHINE(const void *obj)
    {
        return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE);
    }

    static inline G_GNUC_UNUSED MachineClass *MACHINE_GET_CLASS(const void *obj)
    {
        return OBJECT_GET_CLASS(MachineClass, obj, TYPE_MACHINE);
    }

    static inline G_GNUC_UNUSED MachineClass *MACHINE_CLASS(const void *klass)
    {
        return OBJECT_CLASS_CHECK(MachineClass, klass, TYPE_MACHINE);
    }

这就得到了初步形式。再将TYPE_MACHINE宏的定义(在include/hw/boards.h中)代入:

#define TYPE_MACHINE "machine"

得到:

    typedef struct MachineState MachineState;
    typedef struct MachineClass MachineClass;

    G_DEFINE_AUTOPTR_CLEANUP_FUNC(MachineState, object_unref)

    static inline G_GNUC_UNUSED MachineState *MACHINE(const void *obj)
    {
        return OBJECT_CHECK(MachineState, obj, "machine");
    }

    static inline G_GNUC_UNUSED MachineClass *MACHINE_GET_CLASS(const void *obj)
    {
        return OBJECT_GET_CLASS(MachineClass, obj, "machine");
    }

    static inline G_GNUC_UNUSED MachineClass *MACHINE_CLASS(const void *klass)
    {
        return OBJECT_CLASS_CHECK(MachineClass, klass, "machine");
    }

对比一下在VSCode中展开的截图:

QEMU源码全解析38 —— Machine(8),QEMU,KVM,QEMU,KVM

 终于看到了MACHINE函数的庐山真面目!原来是这样:

static inline G_GNUC_UNUSED MachineState *MACHINE(const void *obj)
{
    return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE);
}

下一回将对MACHINE函数及其相关函数进行进一步解析。文章来源地址https://www.toymoban.com/news/detail-650805.html

到了这里,关于QEMU源码全解析38 —— Machine(8)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • QEMU源码全解析 —— PCI设备模拟(6)

    接前一篇文章: 上一回讲到了pci_edu_realize函数中的pci_register_bar函数,本回对于其进行详细解析。 再次贴出pci_register_bar函数源码,在hw/pci/pci.c中,代码如下: (1)首先根据region_num找到PCIDevice-io_regions数组中对应的项。PCI设备的MMIO存放在PCIIORegion结构体中,结构体中保存了

    2024年01月16日
    浏览(36)
  • QEMU源码全解析 —— PCI设备模拟(7)

    接前一篇文章: 上一回讲解了pci_edu_realize函数中的pci_register_bar函数,本回开始对于edu设备的MMIO读写函数进行解析。 操作系统与PCI设备交互的主要方式是PIO和MMIO。MMIO虽然是一段内存,但是其没有EPT映射,在虚拟机访问设备的MMIO时,会产生VM Exit;KVM识别此MMIO访问并且将该访

    2024年01月22日
    浏览(31)
  • qemu-kvm IO优化

    主要是磁盘方面的IO资源优化  四个方面去着手优化: 1. 磁盘的类型有IDE 、SATA 以及virtio 三种   建议使用 virtio 2. 磁盘缓存模式   目前KVM这块支持5种磁盘缓存模式,writethrough、writeback、none、directsync或者unsafe。一般用到的就是前面3种,后面两种几乎不会使用。   writethrou

    2023年04月08日
    浏览(31)
  • kvm qemu虚拟机的创建和启动

    qemu-img create -f qcow2 win1021H1.qcow2 10G sudo qemu-system-x86_64 -enable-kvm -m 8G -smp 4 -boot once=d -cdrom ./iso/cn_windows_7_enterprise_with_sp1_x64_dvd_u_677685.iso -hda ./win7_x64.qcow2 -vnc :1 -usb -usbdevice tablet 如果没有指定-hda ./win7.qcow2,则在安装系统的时候没有磁盘,如下图片是增加了之后才有的磁盘 默认不

    2024年02月12日
    浏览(50)
  • 巨页内存与Qemu/KVM虚拟化内存优化

    在虚拟化环境中,需要对虚拟机的优化,其中包括在某些情况下利用巨页内存进行内存的优化以提高虚拟机性能。那么什么是巨页内存?巨页内存有什么好处?Qemu/KVM虚拟化环境下如何使用巨页内存?本文将对这几个问题进行阐述。 对于内存管理,大多数现代操作系统都采用

    2024年02月07日
    浏览(45)
  • QEMU-KVM网络特性协商与虚拟机通信

    深入了解QEMU-KVM在启动虚拟机时如何通过代理进行网络前后端特性协商,包括与DPDK vhost-user和guest virtio-net驱动的交互。

    2024年02月01日
    浏览(30)
  • python可视化管理kvm虚拟机(使用libvirt、qemu连接虚拟机)

    对于云计算的实践,在虚拟机上面布置kvm虚拟机后使用python调用libvirt库进行远程可视化管理,实现输出虚拟机信息、新建虚拟机、删除虚拟机等功能,并在虚拟机集群上面运行mpi代码。 用pycharm专业版连接kvm的步骤见本文章。 mpi代码见本文章。

    2024年02月16日
    浏览(39)
  • qemu+kvm安装银河麒麟V10SP1 arm64 虚拟机

    系统镜像 Kylin-Desktop-V10-SP1-Release-2107-arm64.iso QEMU_EFI.fd(下载地址 http://releases.linaro.org/components/kernel/uefi-linaro/16.02/release/qemu64/QEMU_EFI.fd) 注:麒麟系统要求磁盘大小在50G以上. 参数说明: -m 4096 指定内存大小,单位MB -cpu cortex-a72 CPU 型号 -smp 8,cores=8,threads=1,sockets=1 1颗CPU,8核8线

    2024年01月21日
    浏览(103)
  • FT2000+ qemu kvm openEuer crash 分析 频繁设置CPU online及cgroup导致进程卡死、不调度故障

    https://hknaruto.blog.csdn.net/article/details/130498823 内核版本信息  突然就坚挺起来,长时间稳定运行 待续 十几分钟后,终端已卡死 ,两个终端均无响应,但是gnome还活着,图形界面还能动 重启虚拟机 kvm内,安装好crash分析环境 下载安装debuginfo包 http://debuginfo.centos.org/8/aarch64/Pack

    2024年02月02日
    浏览(43)
  • ubuntu18.04下pass-through直通realteck PCI设备到qemu-kvm虚拟机实践

    设备直通是一种虚拟化资源分配方式,通过将物理设备直通给虚拟机环境,达到虚拟机可以直接访问物理设备的目的,直通功能对设备的要求不高,不需要设备支持PF/VF,目前市面上的显卡/网卡一般都支持直通。典型场景比如有两块显卡,一块主机用,另一块虚拟机用,主板

    2024年02月03日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包