qemu源码解析【05】qemu启动初始化流程

目录

  • qemu源码解析【05】qemu启动初始化流程
    • [1. qemu入口函数](#1. qemu入口函数)
    • [2. qemu_init()函数内容](#2. qemu_init()函数内容)
      • [2.1 构建参数链表](#2.1 构建参数链表)
      • [2.2 一些系统相关的交互](#2.2 一些系统相关的交互)
      • [2.3 解析启动的命令行参数](#2.3 解析启动的命令行参数)

qemu源码解析【05】qemu启动初始化流程

1. qemu入口函数

  • qemu入口main函数位于system/main.c文件,main函数内容很简单,完成启动前的初始化,进入主循环

    int qemu_default_main(void)
    {
    int status;

    复制代码
      status = qemu_main_loop();
      qemu_cleanup(status);
    
      return status;

    }

    int (*qemu_main)(void) = qemu_default_main;

    int main(int argc, char **argv)
    {
    // 初始化流程
    qemu_init(argc, argv);
    // 主循环函数
    return qemu_main();
    }

  • 这篇文章浅浅研究一下qemu_init(),也就是初始化函数里面的代码

2. qemu_init()函数内容

  • 下面开始逐段分析qemu_init()函数内容

2.1 构建参数链表

复制代码
    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_fw_cfg_opts);
    qemu_add_opts(&qemu_action_opts);
    qemu_add_run_with_opts();
    module_call_init(MODULE_INIT_OPTS);
  • 在util/qemu-config.c中有2个全局的QemuOptsList*数组,vm_config_groups48和drive_config_groups5
  • 以上代码就是在初始化这2个数组,将qemu_drive_opts,qemu_device_opts这些结构体填到这2个数组中,这里面存的其实就是qemu启动时我们传进去的那些参数,或者我们没有指定这些一些参数,系统帮我们给定了一个默认值
  • 然后还有个module_call_init()函数,作用跟上一章的qom链表初始化过程差不多,就是根据init_type_listMODULE_INIT_OPTS链表上挂的所有成员,挨个初始化

2.2 一些系统相关的交互

复制代码
    // 初始化glib的日志库
    error_init(argv[0]);

    // 找到当前执行的文件路径,存在静态变量exec_dir中
    qemu_init_exec_dir(argv[0]);

    // 保存当前机器的一些架构信息
    os_setup_limits();
    qemu_init_arch_modules();

    // 初始化子系统,例如上文说到的那个QOM链表
    qemu_init_subsystems();

2.3 解析启动的命令行参数

  • qemu自带了一个字典库,位于qobject/qdict.c文件中

  • 解析命令行参数之前,先创建了一个字典库,用来保存所有解析结果

  • 这段解析参数很多,但逻辑很简单,就是机械地解析所有参数,然后保存到字典中,以下做了删除

  • 可以看到,我们传入的cpu,hda,smp等所有的参数都在此处完成和解析和保存

    复制代码
      machine_opts_dict = qdict_new();
      if (userconfig) {
          qemu_read_default_config_file(&error_fatal);
      }
    
      /* second pass of option parsing */
      optind = 1;
      for(;;) {
          if (optind >= argc)
              break;
          if (argv[optind][0] != '-') {
              loc_set_cmdline(argv, optind, 1);
              drive_add(IF_DEFAULT, 0, argv[optind++], HD_OPTS);
          } else {
              const QEMUOption *popt;
    
              popt = lookup_opt(argc, argv, &optarg, &optind);
              if (!(popt->arch_mask & arch_type)) {
                  error_report("Option not supported for this target");
                  exit(1);
              }
              switch(popt->index) {
              case QEMU_OPTION_cpu:
              
                  /* hw initialization will check this */
                  cpu_option = optarg;
                  break;
              case QEMU_OPTION_hda:
              case QEMU_OPTION_hdb:
              case QEMU_OPTION_hdc:
              case QEMU_OPTION_hdd:
                  drive_add(IF_DEFAULT, popt->index - QEMU_OPTION_hda, optarg,
                            HD_OPTS);
                  break;
             // 此处省略
             // .......
    
              default:
                  error_report("Option not supported in this build");
                  exit(1);
              }
          }
      }
相关推荐
划破黑暗的第一缕曙光1 小时前
[C++]:2.类和对象(下)
c++·类和对象·对象·类
黎相思3 小时前
LRU Cache
c++·缓存
UIU1143 小时前
P1003 [NOIP 2011 提高组] 铺地毯
数据结构·c++·算法
ABB自动化3 小时前
带二期控制的PowerFlex 700S驱动器
驱动开发·制造·信息与通信·模块测试·plc 控制器
xxwl5854 小时前
区域赛算法模版第四章---数据结构
数据结构·c++·算法
额额额对了5 小时前
Linux 驱动开发:基于 platform 总线 + misc 设备的 DS18B20 单总线温度驱动
linux·c语言·开发语言·驱动开发·嵌入式硬件
余额瞒着我当琳6 小时前
哈希表底层原理解析,直接定址法,哈希冲突,负载因子,哈希函数,开放定址法
java·c++·哈希算法·散列表
xxwl5856 小时前
区域赛算法模版第五章---数学与数论
c++·笔记·算法
局部有解7 小时前
LeetCode Hot100 438 找到字符串中所有字母异位词
c++·算法·leetcode
David猪大卫7 小时前
【C++修炼】string类:string类的模拟实现
c语言·开发语言·数据结构·c++·经验分享·笔记·学习