接前一篇文章: 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,这是非常关键的一步,因此我放在了主函数之后第一个要讲解的位置。不过本回只是起个头,预知此函数详情,请看下回。