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

88 篇文章 19 订阅
本文深入解析QEMU如何解析众多参数。QEMUOption结构存储所有可用选项,通过lookup_opt函数处理命令行参数。qemu_options数组结合qemu-options.def文件(由qemu-options.hx生成)包含所有可能的参数。编译QEMU后,可以在build目录下找到详细的qemu-options.def文件。后续将继续探讨QEMUOption和参数解析的更多内容。
摘要由CSDN通过智能技术生成

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

本文内容参考:

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

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

特此致谢!

上回说到如此多的参数是如何被QEMU解析的,本节就来看一下具体的解析过程。

QEMU使用QEMUOption来表示QEMU程序的参数选项,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;

其中:

  • name:表示参数选项的名称。
  • flags:表示选项中一些参数选项的属性,比如是否有子参数。
  • arch_mask表示参数支持的体系结构。

softmmu/vl.c在全局范围内定义了一个QEMUOption结构的变量qemu_options,存储了所有的可用选项,代码如下:

  1. static const QEMUOption qemu_options[] = {
  2. { "h", 0, QEMU_OPTION_h, QEMU_ARCH_ALL },
  3. #define DEF(option, opt_arg, opt_enum, opt_help, arch_mask) \
  4. { option, opt_arg, opt_enum, arch_mask },
  5. #define DEFHEADING(text)
  6. #define ARCHHEADING(text, arch_mask)
  7. #include "qemu-options.def"
  8. { /* end of list */ }
  9. };

main函数中会调用lookup_opt来解析QEMU命令行参数,不在qemu_options中的参数是不合法的。代码如下:

  1. static const QEMUOption *lookup_opt(int argc, char **argv,
  2. const char **poptarg, int *poptind)
  3. {
  4. const QEMUOption *popt;
  5. int optind = *poptind;
  6. char *r = argv[optind];
  7. const char *optarg;
  8. loc_set_cmdline(argv, optind, 1);
  9. optind++;
  10. /* Treat --foo the same as -foo. */
  11. if (r[1] == '-')
  12. r++;
  13. popt = qemu_options;
  14. for(;;) {
  15. if (!popt->name) {
  16. error_report("invalid option");
  17. exit(1);
  18. }
  19. if (!strcmp(popt->name, r + 1))
  20. break;
  21. popt++;
  22. }
  23. if (popt->flags & HAS_ARG) {
  24. if (optind >= argc) {
  25. error_report("requires an argument");
  26. exit(1);
  27. }
  28. optarg = argv[optind++];
  29. loc_set_cmdline(argv, optind - 2, 2);
  30. } else {
  31. optarg = NULL;
  32. }
  33. *poptarg = optarg;
  34. *poptind = optind;
  35. return popt;
  36. }

有的读者可能会有疑问,static const QEMUOption qemu_options[]结构体数组中也没有几项啊,是如何做到解析那么多参数的?你得仔细看,结构体中有这样一行代码:

#include "qemu-options.def"

再来看看qemu-options.def文件的内容。搜索这个文件结果没有搜索到,要在编译QEMU源码后,这个文件才会生成(实际上是在Makefile中利用scripts/hxtool脚本根据qemu-options.hx文件生成的)。按照 QEMU零知识学习3 —— QEMU配置_qemu 配置文件_蓝天居士的博客-CSDN博客

中的方法,在QEMU源码根目录下运行./configure进行配置。光配置还不够,还得按照 QEMU零知识学习4 —— QEMU编译_蓝天居士的博客-CSDN博客

中的方法,在QEMU源码根目录下运行make进行编译构建才可以。最终在build目录下会生成qemu-options.def文件,文件内容如下(一共1000多行,仅截取部分内容):

  1. DEFHEADING(Standard options:)
  2. DEF("help", 0, QEMU_OPTION_h,
  3. "-h or -help display this help and exit\n", QEMU_ARCH_ALL)
  4. DEF("version", 0, QEMU_OPTION_version,
  5. "-version display version information and exit\n", QEMU_ARCH_ALL)
  6. DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
  7. "-machine [type=]name[,prop[=value][,...]]\n"
  8. " selects emulated machine ('-machine help' for list)\n"
  9. " property accel=accel1[:accel2[:...]] selects accelerator\n"
  10. " supported accelerators are kvm, xen, hax, hvf, nvmm, whpx or tcg (default: tcg)\n"
  11. " vmport=on|off|auto controls emulation of vmport (default: auto)\n"
  12. " dump-guest-core=on|off include guest memory in a core dump (default=on)\n"
  13. " mem-merge=on|off controls memory merge support (default: on)\n"
  14. " aes-key-wrap=on|off controls support for AES key wrapping (default=on)\n"
  15. " dea-key-wrap=on|off controls support for DEA key wrapping (default=on)\n"
  16. " suppress-vmdesc=on|off disables self-describing migration (default=off)\n"
  17. " nvdimm=on|off controls NVDIMM support (default=off)\n"
  18. " memory-encryption=@var{} memory encryption object to use (default=none)\n"
  19. " hmat=on|off controls ACPI HMAT support (default=off)\n"
  20. " memory-backend='backend-id' specifies explicitly provided backend for main RAM (default=none)\n"
  21. " cxl-fmw.0.targets.0=firsttarget,cxl-fmw.0.targets.1=secondtarget,cxl-fmw.0.size=size[,cxl-fmw.0.interleave-granularity=granularity]\n",
  22. QEMU_ARCH_ALL)
  23. DEF("M", HAS_ARG, QEMU_OPTION_M,
  24. " sgx-epc.0.memdev=memid,sgx-epc.0.node=numaid\n",
  25. QEMU_ARCH_ALL)
  26. DEF("cpu", HAS_ARG, QEMU_OPTION_cpu,
  27. "-cpu cpu select CPU ('-cpu help' for list)\n", QEMU_ARCH_ALL)
  28. DEF("accel", HAS_ARG, QEMU_OPTION_accel,
  29. "-accel [accel=]accelerator[,prop[=value][,...]]\n"
  30. " select accelerator (kvm, xen, hax, hvf, nvmm, whpx or tcg; use 'help' for a list)\n"
  31. " igd-passthru=on|off (enable Xen integrated Intel graphics passthrough, default=off)\n"
  32. " kernel-irqchip=on|off|split controls accelerated irqchip support (default=on)\n"
  33. " kvm-shadow-mem=size of KVM shadow MMU in bytes\n"
  34. " split-wx=on|off (enable TCG split w^x mapping)\n"
  35. " tb-size=n (TCG translation block cache size)\n"
  36. " dirty-ring-size=n (KVM dirty ring GFN count, default 0)\n"
  37. " thread=single|multi (enable multi-threaded TCG)\n", QEMU_ARCH_ALL)
  38. DEF("smp", HAS_ARG, QEMU_OPTION_smp,
  39. "-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,clusters=clusters][,cores=cores][,threads=threads]\n"
  40. " set the number of initial CPUs to 'n' [default=1]\n"
  41. " maxcpus= maximum number of total CPUs, including\n"
  42. " offline CPUs for hotplug, etc\n"
  43. " sockets= number of sockets on the machine board\n"
  44. " dies= number of dies in one socket\n"
  45. " clusters= number of clusters in one die\n"
  46. " cores= number of cores in one cluster\n"
  47. " threads= number of threads in one core\n"
  48. "Note: Different machines may have different subsets of the CPU topology\n"
  49. " parameters supported, so the actual meaning of the supported parameters\n"
  50. " will vary accordingly. For example, for a machine type that supports a\n"
  51. " three-level CPU hierarchy of sockets/cores/threads, the parameters will\n"
  52. " sequentially mean as below:\n"
  53. " sockets means the number of sockets on the machine board\n"
  54. " cores means the number of cores in one socket\n"
  55. " threads means the number of threads in one core\n"
  56. " For a particular machine type board, an expected CPU topology hierarchy\n"
  57. " can be defined through the supported sub-option. Unsupported parameters\n"
  58. " can also be provided in addition to the sub-option, but their values\n"
  59. " must be set as 1 in the purpose of correct parsing.\n",
  60. QEMU_ARCH_ALL)
  61. DEF("numa", HAS_ARG, QEMU_OPTION_numa,
  62. "-numa node[,mem=size][,cpus=firstcpu[-lastcpu]][,nodeid=node][,initiator=node]\n"
  63. "-numa node[,memdev=id][,cpus=firstcpu[-lastcpu]][,nodeid=node][,initiator=node]\n"
  64. "-numa dist,src=source,dst=destination,val=distance\n"
  65. "-numa cpu,node-id=node[,socket-id=x][,core-id=y][,thread-id=z]\n"
  66. "-numa hmat-lb,initiator=node,target=node,hierarchy=memory|first-level|second-level|third-level,data-type=access-latency|read-latency|write-latency[,latency=lat][,bandwidth=bw]\n"
  67. "-numa hmat-cache,node-id=node,size=size,level=level[,associativity=none|direct|complex][,policy=none|write-back|write-through][,line=size]\n",
  68. QEMU_ARCH_ALL)
  69. ……
  70. #ifndef _WIN32
  71. DEF("chroot", HAS_ARG, QEMU_OPTION_chroot, \
  72. "-chroot dir chroot to dir just before starting the VM\n",
  73. QEMU_ARCH_ALL)
  74. #endif
  75. #ifndef _WIN32
  76. DEF("runas", HAS_ARG, QEMU_OPTION_runas, \
  77. "-runas user change to user id user just before starting the VM\n" \
  78. " user can be numeric uid:gid instead\n",
  79. QEMU_ARCH_ALL)
  80. #endif
  81. DEF("prom-env", HAS_ARG, QEMU_OPTION_prom_env,
  82. "-prom-env variable=value\n"
  83. " set OpenBIOS nvram variables\n",
  84. QEMU_ARCH_PPC | QEMU_ARCH_SPARC)
  85. DEF("semihosting", 0, QEMU_OPTION_semihosting,
  86. "-semihosting semihosting mode\n",
  87. QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA |
  88. QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV)
  89. DEF("semihosting-config", HAS_ARG, QEMU_OPTION_semihosting_config,
  90. "-semihosting-config [enable=on|off][,target=native|gdb|auto][,chardev=id][,arg=str[,...]]\n" \
  91. " semihosting configuration\n",
  92. QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA |
  93. QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV)
  94. DEF("old-param", 0, QEMU_OPTION_old_param,
  95. "-old-param old param mode\n", QEMU_ARCH_ARM)
  96. DEF("sandbox", HAS_ARG, QEMU_OPTION_sandbox, \
  97. "-sandbox on[,obsolete=allow|deny][,elevateprivileges=allow|deny|children]\n" \
  98. " [,spawn=allow|deny][,resourcecontrol=allow|deny]\n" \
  99. " Enable seccomp mode 2 system call filter (default 'off').\n" \
  100. " use 'obsolete' to allow obsolete system calls that are provided\n" \
  101. " by the kernel, but typically no longer used by modern\n" \
  102. " C library implementations.\n" \
  103. " use 'elevateprivileges' to allow or deny the QEMU process ability\n" \
  104. " to elevate privileges using set*uid|gid system calls.\n" \
  105. " The value 'children' will deny set*uid|gid system calls for\n" \
  106. " main QEMU process but will allow forks and execves to run unprivileged\n" \
  107. " use 'spawn' to avoid QEMU to spawn new threads or processes by\n" \
  108. " blocking *fork and execve\n" \
  109. " use 'resourcecontrol' to disable process affinity and schedular priority\n",
  110. QEMU_ARCH_ALL)
  111. DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig,
  112. "-readconfig <file>\n"
  113. " read config file\n", QEMU_ARCH_ALL)
  114. DEF("no-user-config", 0, QEMU_OPTION_nouserconfig,
  115. "-no-user-config\n"
  116. " do not load default user-provided config files at startup\n",
  117. QEMU_ARCH_ALL)
  118. DEF("trace", HAS_ARG, QEMU_OPTION_trace,
  119. "-trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
  120. " specify tracing options\n",
  121. QEMU_ARCH_ALL)
  122. DEF("plugin", HAS_ARG, QEMU_OPTION_plugin,
  123. "-plugin [file=]<file>[,<argname>=<argvalue>]\n"
  124. " load a plugin\n",
  125. QEMU_ARCH_ALL)
  126. DEF("qtest", HAS_ARG, QEMU_OPTION_qtest, "", QEMU_ARCH_ALL)
  127. DEF("qtest-log", HAS_ARG, QEMU_OPTION_qtest_log, "", QEMU_ARCH_ALL)
  128. DEF("msg", HAS_ARG, QEMU_OPTION_msg,
  129. "-msg [timestamp[=on|off]][,guest-name=[on|off]]\n"
  130. " control error message format\n"
  131. " timestamp=on enables timestamps (default: off)\n"
  132. " guest-name=on enables guest name prefix but only if\n"
  133. " -name guest option is set (default: off)\n",
  134. QEMU_ARCH_ALL)
  135. DEF("dump-vmstate", HAS_ARG, QEMU_OPTION_dump_vmstate,
  136. "-dump-vmstate <file>\n"
  137. " Output vmstate information in JSON format to file.\n"
  138. " Use the scripts/vmstate-static-checker.py file to\n"
  139. " check for possible regressions in migration code\n"
  140. " by comparing two such vmstate dumps.\n",
  141. QEMU_ARCH_ALL)
  142. DEF("enable-sync-profile", 0, QEMU_OPTION_enable_sync_profile,
  143. "-enable-sync-profile\n"
  144. " enable synchronization profiling\n",
  145. QEMU_ARCH_ALL)
  146. DEFHEADING()
  147. DEFHEADING(Generic object creation:)
  148. DEF("object", HAS_ARG, QEMU_OPTION_object,
  149. "-object TYPENAME[,PROP1=VALUE1,...]\n"
  150. " create a new object of type TYPENAME setting properties\n"
  151. " in the order they are specified. Note that the 'id'\n"
  152. " property must be set. These objects are placed in the\n"
  153. " '/objects' path.\n",
  154. QEMU_ARCH_ALL)
  155. #undef DEF
  156. #undef DEFHEADING
  157. #undef ARCHHEADING

这里只需要理解qemu_options中包括了所有可能的参数选项,如上边的“-enable- kvm ”、“-smp”、“-realtime”、“-device”等即可。

欲知QEMUOption以及QEMU参数解析的更多细节,且看下回分解。

举报

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