前面我们讲了KVM内核层创建及初始化虚拟机的一些工作过程,现在讲一下Qemu层的流程以及与KVM内核层的配合过程。
Qemu层是从vl.c中的main()函数开始的,这里通过在代码中添加一些注释的方式来进行讲解,中间省略了很多不重要或者我也没有搞清楚的代码。 囧
int main(int argc, char **argv, char **envp)
{
......
atexit(qemu_run_exit_notifiers);//注册了Qemu的退出函数
......
module_call_init(MODULE_INIT_QOM);//初始化Qemu的各个模块,具体见下面注释
/*
module_call_init实际上是设计了一个函数链表ModuleTypeList,参数作为一个Type,相关的函数注册到这个函数链表上,
然后内部通过调用e->init()函数完成所有Type相关的设备的初始化。关于e->init()的具体内容后面再细说。
Type总计有这些类型:
typedef enum {
MODULE_INIT_BLOCK,
MODULE_INIT_MACHINE,
MODULE_INIT_QAPI,
MODULE_INIT_QOM,
MODULE_INIT_MAX
} module_init_type;
*/
qemu_add_opts(&qemu_drive_opts);//将各种函数指针(也就是操作)集合添加到链表中
qemu_add_opts(&qemu_chardev_opts);
qemu_add_opts(&qemu_device_opts);
qemu_add_opts(&qemu_netdev_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_add_opts(&qemu_option_rom_opts);
qemu_add_opts(&qemu_machine_opts);
qemu_add_opts(&qemu_boot_opts);
qemu_add_opts(&qemu_sandbox_opts);
qemu_add_opts(&qemu_add_fd_opts);
qemu_add_opts(&qemu_object_opts);
qemu_add_opts(&qemu_tpmdev_opts);
qemu_add_opts(&qemu_realtime_opts);
......
init_clocks();//时钟初始化相关
rtc_clock = host_clock;
......
module_call_init(MODULE_INIT_MACHINE);
machine = find_default_machine();
......
......
cpudef_init();//初始化CPU def相关
......
if (log_mask) {//日志相关的设置,KVM对外的日志在这里配置
int mask;
if (log_file) {
qemu_set_log_filename(log_file);
}
mask = qemu_str_to_log_mask(log_mask);
if (!mask) {
qemu_print_log_usage(stdout);
exit(1);
}
qemu_set_log(mask);
}
......
configure_accelerator();//进行虚拟机模拟器的配置,这里重点注意,它