QEMU源码全解析3 —— QEMU参数解析(3)

88 篇文章 19 订阅
本文深入解析QEMUOptions结构和全局变量qemu_options,介绍QEMU如何处理参数。通过QEMUOption、QemuOptsList等数据结构,阐述QEMU参数的组织方式,特别是-machine、-overcommit和-device选项的处理。同时引用《趣谈Linux操作系统》和《QEMU/KVM》相关资料,探讨QEMU参数解析的实现细节。
摘要由CSDN通过智能技术生成

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

本文内容参考:

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

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

特此致谢!

上回说到QEMUOptions结构以及全局变量qemu_options,本节继续对其进行深入探究。

为便于理解和会议,在此再贴出QEMUOption结构的代码,在softmmu/vl.c中:

  1. typedef struct QEMUOption {
  2. const char *name;
  3. int flags;
  4. int index;
  5. uint32_t arch_mask;
  6. } QEMUOption;

QEMUOption提供了参数的基本信息情况。实际参数的保存是由3个数据结构完成的。

QEMU将所有参数分成了几个大选项,也可以叫类,如-enable- kvm 和- kernel 都属于machine相关的,每个大选项使用struct QemuOptsList结构体表示,其定义在include/qemu/option.h中,代码如下:

  1. struct QemuOptsList {
  2. const char *name;
  3. const char *implied_opt_name;
  4. bool merge_lists; /* Merge multiple uses of option into a single list? */
  5. QTAILQ_HEAD(, QemuOpts) head;
  6. QemuOptDesc desc[];
  7. };

QEMU在util/qemu-config.c中定义了struct QemuOptsList类型的全局变量vm_config_groups,代码如下:

  1. static QemuOptsList *vm_config_groups[48];
  2. static QemuOptsList *drive_config_groups[5];

这表示可以支持48个大选项。在main函数(softmmu/vl.c的qemu_init函数)中用qemu_add_opts将各个OemuOptsList添加到vm_config_groups中。

终于回到了本系列第一篇文章中就给出的代码,在softmmu/vl.c中的void qemu_init(int argc, char **argv)中:

  1. qemu_add_opts(&qemu_drive_opts);
  2. qemu_add_drive_opts(&qemu_legacy_drive_opts);
  3. qemu_add_drive_opts(&qemu_common_drive_opts);
  4. qemu_add_drive_opts(&qemu_drive_opts);
  5. qemu_add_drive_opts(&bdrv_runtime_opts);
  6. qemu_add_opts(&qemu_chardev_opts);
  7. qemu_add_opts(&qemu_device_opts);
  8. qemu_add_opts(&qemu_netdev_opts);
  9. qemu_add_opts(&qemu_nic_opts);
  10. qemu_add_opts(&qemu_net_opts);
  11. qemu_add_opts(&qemu_rtc_opts);
  12. qemu_add_opts(&qemu_global_opts);
  13. qemu_add_opts(&qemu_mon_opts);
  14. qemu_add_opts(&qemu_trace_opts);
  15. qemu_plugin_add_opts();
  16. qemu_add_opts(&qemu_option_rom_opts);
  17. qemu_add_opts(&qemu_accel_opts);
  18. qemu_add_opts(&qemu_mem_opts);
  19. qemu_add_opts(&qemu_smp_opts);
  20. qemu_add_opts(&qemu_boot_opts);
  21. qemu_add_opts(&qemu_add_fd_opts);
  22. qemu_add_opts(&qemu_object_opts);
  23. qemu_add_opts(&qemu_tpmdev_opts);
  24. qemu_add_opts(&qemu_overcommit_opts);
  25. qemu_add_opts(&qemu_msg_opts);
  26. qemu_add_opts(&qemu_name_opts);
  27. qemu_add_opts(&qemu_numa_opts);
  28. qemu_add_opts(&qemu_icount_opts);
  29. qemu_add_opts(&qemu_semihosting_config_opts);
  30. qemu_add_opts(&qemu_fw_cfg_opts);
  31. qemu_add_opts(&qemu_action_opts);

是时候来看一下qemu_add_opts的实现了,在util/qemu-config.c中,代码如下:

  1. void qemu_add_opts(QemuOptsList *list)
  2. {
  3. int entries, i;
  4. entries = ARRAY_SIZE(vm_config_groups);
  5. entries--; /* keep list NULL terminated */
  6. for (i = 0; i < entries; i++) {
  7. if (vm_config_groups[i] == NULL) {
  8. vm_config_groups[i] = list;
  9. return;
  10. }
  11. }
  12. fprintf(stderr, "ran out of space in vm_config_groups");
  13. abort();
  14. }

该函数实现了如上所述的功能:qemu_add_opts将各个OemuOptsList添加到vm_config_groups(static QemuOptsList *vm_config_groups[48])中。

每个QemuOptsList存储了大选项支持的所有小选项,比如-overcommit大选项定义如下(softmmu/vl.c中):

  1. static QemuOptsList qemu_overcommit_opts = {
  2. .name = "overcommit",
  3. .head = QTAILQ_HEAD_INITIALIZER(qemu_overcommit_opts.head),
  4. .desc = {
  5. {
  6. .name = "mem-lock",
  7. .type = QEMU_OPT_BOOL,
  8. },
  9. {
  10. .name = "cpu-pm",
  11. .type = QEMU_OPT_BOOL,
  12. },
  13. { /* end of list */ }
  14. },
  15. };

-overcommit只支持两个值为bool(QEMU_OPT_BOOL)的子选项,即只能有-overcommit mem-lock=on/off和-overcommit cpu-pm=on/off。

但是有些大选项就并不是这样了,比如-device这个(种)选项就没有这么死板了。-device大选项定义如下(同样在oftmmu/vl.c中):

  1. QemuOptsList qemu_device_opts = {
  2. .name = "device",
  3. .implied_opt_name = "driver",
  4. .head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
  5. .desc = {
  6. /*
  7. * no elements => accept any
  8. * sanity checking will happen later
  9. * when setting device properties
  10. */
  11. { /* end of list */ }
  12. },
  13. };

-device并没有规定必需的选项,因为设备有无数多种,不可能全部进行规定,解析就是按照“,”或者“=”来进行的。每个子选项由一个QemuOpt结构表示。

关于QemuOpt结构的具体定义以及QemuOptsList、QemuOpt、QemuOpts等结构之间的关系,且看下回分解。

举报

选择你想要举报的内容(必选)
  • 内容涉黄
  • 政治相关
  • 内容抄袭
  • 涉嫌广告
  • 内容侵权
  • 侮辱谩骂
  • 样式问题
  • 其他