QEMU源码全解析7 —— QEMU主函数

接前一篇文章:QEMU源码全解析6 —— QEMU参数解析(6)

本文内容参考:

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

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

特此致谢!

本系列前几篇文章一直在围绕QEMU参数解析进行讲解,本篇文章开始我们换一个角度研究,从QEMU主函数作为入口进行深入。

前边文章提到QEMU的主函数是softmmu/vl.c中的qemu_init(),实际上并不是,而是真正有main函数的。老版本的main函数位于softmmu/vl.c中;而在较新的版本(笔者的版本是qemu-7.1.0)中,main函数被单独放到了softmmu/main.c中。代码如下:

int qemu_main(int argc, char **argv, char **envp)
{
    int status;

    qemu_init(argc, argv, envp);
    status = qemu_main_loop();
    qemu_cleanup();

    return status;
}

#ifndef CONFIG_COCOA
int main(int argc, char **argv)
{
    return qemu_main(argc, argv, NULL);
}
#endif

可以看到,main函数中只是简单调用了qemu_main函数,将实际的工作交给了它,即真正的QEMU主函数实际上是qemu_main()。

qemu_main()中一共包括三大函数:qemu_init、qemu_mail_loop、qemu_cleanup。之所以说是大函数,是因为虽然看似简单,但其里边包含的代码和内容多了去了。

接下来看一下qemu_init函数中的一句module_call_init(MODULE_INIT_QDOM)。为了便于理解,把qemu_init函数的代码片段在此贴出:

void qemu_init(int argc, char **argv, char **envp)
{
    QemuOpts *opts;
    QemuOpts *icount_opts = NULL, *accel_opts = NULL;
    QemuOptsList *olist;
    int optind;
    const char *optarg;
    MachineClass *machine_class;
    bool userconfig = true;
    FILE *vmstate_dump_file = NULL;

    qemu_add_opts(&qemu_drive_opts);
    qemu_add_drive_opts(&qemu_legacy_drive_opts);
    qemu_add_drive_opts(&qemu_common_drive_opts);
    qemu_add_drive_opts(&qemu_drive_opts);
    qemu_add_drive_opts(&bdrv_runtime_opts);
    qemu_add_opts(&qemu_chardev_opts);
    qemu_add_opts(&qemu_device_opts);
    qemu_add_opts(&qemu_netdev_opts);
    qemu_add_opts(&qemu_nic_opts);
    qemu_add_opts(&qemu_net_opts);
    qemu_add_opts(&qemu_rtc_opts);
    qemu_add_opts(&qemu_global_opts);
    qemu_add_opts(&qemu_mon_opts);
    qemu_add_opts(&qemu_trace_opts);
    qemu_plugin_add_opts();
    qemu_add_opts(&qemu_option_rom_opts);
    qemu_add_opts(&qemu_accel_opts);
    qemu_add_opts(&qemu_mem_opts);
    qemu_add_opts(&qemu_smp_opts);
    qemu_add_opts(&qemu_boot_opts);
    qemu_add_opts(&qemu_add_fd_opts);
    qemu_add_opts(&qemu_object_opts);
    qemu_add_opts(&qemu_tpmdev_opts);
    qemu_add_opts(&qemu_overcommit_opts);
    qemu_add_opts(&qemu_msg_opts);
    qemu_add_opts(&qemu_name_opts);
    qemu_add_opts(&qemu_numa_opts);
    qemu_add_opts(&qemu_icount_opts);
    qemu_add_opts(&qemu_semihosting_config_opts);
    qemu_add_opts(&qemu_fw_cfg_opts);
    qemu_add_opts(&qemu_action_opts);
    module_call_init(MODULE_INIT_OPTS);
……
}

顾名思义,module_call_init(MODULE_INIT_OPTS)函数的作用是初始化所有的Module,这是非常关键的一步,因此我放在了主函数之后第一个要讲解的位置。不过本回只是起个头,预知此函数详情,请看下回。

猜你喜欢

转载自blog.csdn.net/phmatthaus/article/details/131779118