虚拟机的创建

时间:2022-12-24 16:52:05
首先用type_init(kvm_type_init);来定义kvm_type_init,而type_init 定义如下:
#define type_init(function) module_init(function, MODULE_INIT_QOM)
#define module_init(function, type)                                         \
static void __attribute__((constructor)) do_qemu_init_ ## function(void)    \
{                                                                           \
    register_module_init(function, type);                                   \
}

这些以constructor为__attribute__的函数会在vl.c main中被调用

  module_call_init(MODULE_INIT_TRACE);

void module_call_init(module_init_type type)
{
    ModuleTypeList *l;
    ModuleEntry *e;

    l = find_type(type);

    QTAILQ_FOREACH(e, l, node) {
        e->init();
    }
}
找到所有MODULE_INIT_TRACE的module,分别调用其init函数.

static void kvm_type_init(void)

{
    type_register_static(&kvm_accel_type);
}
调用type_register_static 来注册一个kvm_accel_type,而kvm_accel_type的定义如下:
static const TypeInfo kvm_accel_type = {
    .name = TYPE_KVM_ACCEL,
    .parent = TYPE_ACCEL,
    .class_init = kvm_accel_class_init,
    .instance_size = sizeof(KVMState),
};
其class_init 为kvm_accel_class_init
static void kvm_accel_class_init(ObjectClass *oc, void *data)
{
    AccelClass *ac = ACCEL_CLASS(oc);
    ac->name = "KVM";
    ac->init_machine = kvm_init;
    ac->allowed = &kvm_allowed;
}
终于看到kvm_init了,具体是在accel_init_machine 函数中调用的
static int accel_init_machine(AccelClass *acc, MachineState *ms)
{
     ret = acc->init_machine(ms);
}

static int kvm_init(MachineState *ms)
{

    QLIST_INIT(&s->kvm_parked_vcpus);
    s->vmfd = -1;
    s->fd = qemu_open("/dev/kvm", O_RDWR);
    if (s->fd == -1) {
        fprintf(stderr, "Could not access KVM kernel module: %m\n");
        ret = -errno;
        goto err;
    }
   

    do {
        ret = kvm_ioctl(s, KVM_CREATE_VM, type);
    } while (ret == -EINTR);
    s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO);

 }

kvm_init首先打开/dev/kvm,然后的得到的fd,通过ioctl调用KVM_CREATE_VM 来创建虚拟机.最后通过一系列的kvm_check_extension 来初始化s,而s是一个KVMState对象.