QEMU 소스 코드 전체 분석 33 - 기계 (3)

이전 기사에서 계속: QEMU 소스 코드의 전체 분석 32 —— Machine (2)

이 문서의 내용에 대한 참조:

" Linux 운영 체제 에 대한 흥미로운 이야기 " —— Liu Chao, Geek Time

" QEMU /KVM" 소스 코드 분석 및 적용 - Li Qiang, Machinery Industry Press

매우 감사합니다!

이전 두 기사에서는 Intel 440FX 마더보드의 아키텍처와 마더보드를 시뮬레이트하는 QEMU를 소개했습니다. 이 장의 시작 부분에서 QEMU의 마더보드 시뮬레이션 및 초기화를 설명하기 위해 여러 기사를 사용할 것입니다.

가상 머신 초기화

QEMU 마더보드 시뮬레이션의 해당 유형은 MachineClass이며 정렬 파일에는 주로 hw/core/machine.c, hw/i386/pc_piix.c가 포함됩니다. 여기서 머신은 가상 머신 시뮬레이션에서 마더보드의 상태를 보여줍니다. 이 기사에서는 i440FX+piix3 마더보드를 예로 들어 설명합니다.

기계 유형의 정의는 hw/i386/pc_piix.c에 정의된 DEFINE_I440FX_MACHINE 매크로를 통해 수행되며 코드는 다음과 같습니다.

#define DEFINE_I440FX_MACHINE(suffix, name, compatfn, optionfn) \
    static void pc_init_##suffix(MachineState *machine) \
    { \
        void (*compat)(MachineState *m) = (compatfn); \
        if (compat) { \
            compat(machine); \
        } \
        pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
                 TYPE_I440FX_PCI_DEVICE); \
    } \
    DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn)

DEFINE_I440FX_MACHINE의 정의는 함수와 다른 매크로 DEFINE_PC_MACHINE을 포함하여 비교적 간단합니다. DEFINE_PC_MACHINE은 include/hw/i386/pc.h에 정의되어 있으며 코드는 다음과 같습니다.

#define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \
    static void pc_machine_##suffix##_class_init(ObjectClass *oc, void *data) \
    { \
        MachineClass *mc = MACHINE_CLASS(oc); \
        optsfn(mc); \
        mc->init = initfn; \
    } \
    static const TypeInfo pc_machine_type_##suffix = { \
        .name       = namestr TYPE_MACHINE_SUFFIX, \
        .parent     = TYPE_PC_MACHINE, \
        .class_init = pc_machine_##suffix##_class_init, \
    }; \
    static void pc_machine_init_##suffix(void) \
    { \
        type_register(&pc_machine_type_##suffix); \
    } \
    type_init(pc_machine_init_##suffix)

DEFINE_PC_MACHINE 매크로에는 pc_machine_##suffix##class_init 함수가 정의되어 있는데 함수 이름에서 알 수 있듯이 이는 machine_class를 종이 위의 클래스에서 Class 객체로 초기화하는 방식이다. 이 함수에서는 Class 객체인 MachineClass 객체가 생성됩니다. MachineClass 객체의 init 함수는 위에서 정의한 pc_init##suffix를 가리키며, 이 함수는 기계의 종류에 따라 초기화되는 함수이며 나중에 호출될 것임을 나타냅니다.

그런 다음 DEFINE_PC_MACHINE은 종이에 클래스를 생성하기 위한 원시 자료인 pc_machine_type_##suffix의 TypeInfo를 정의하고 type_init 함수는 나중에 호출됩니다.

각각의 새 릴리스는 새 머신 유형을 정의합니다. 다음은 hw/i386/pc_piix.c에 있는 몇 가지 예입니다.

DEFINE_I440FX_MACHINE(v7_1, "pc-i440fx-7.1", NULL,
                      pc_i440fx_7_1_machine_options);
DEFINE_I440FX_MACHINE(v7_0, "pc-i440fx-7.0", NULL,
                      pc_i440fx_7_0_machine_options);
DEFINE_I440FX_MACHINE(v6_2, "pc-i440fx-6.2", NULL,
                      pc_i440fx_6_2_machine_options);
......
DEFINE_I440FX_MACHINE(v1_5, "pc-i440fx-1.5", pc_compat_1_5_fn,
                      pc_i440fx_1_5_machine_options);
DEFINE_I440FX_MACHINE(v1_4, "pc-i440fx-1.4", pc_compat_1_4_fn,
                      pc_i440fx_1_4_machine_options);

예시를 위해 최신 버전 7.1을 예로 들어 보겠습니다.

DEFINE_I440FX_MACHINE(v7_1, "pc-i440fx-7.1", NULL,
                      pc_i440fx_7_1_machine_options);

먼저 예비 확장을 수행하여 다음을 얻습니다.

static void pc_init_v7_1(MachineState *machine)
{
        void (*compat)(MachineState *m) = (NULL);
        if (compat) {
            compat(machine);
        }
        pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
                 TYPE_I440FX_PCI_DEVICE);
    }
    DEFINE_PC_MACHINE(v7_1, "pc-i440fx-7.1", pc_init_v7_1, pc_i440fx_7_1_machine_options)

그런 다음 DEFINE_PC_MACHINE을 확장하여 다음을 얻습니다.

static void pc_init_v7_1(MachineState *machine)
{
        void (*compat)(MachineState *m) = (NULL);
        if (compat) {
            compat(machine);
        }
        pc_init1(machine, TYPE_I440FX_PCI_HOST_BRIDGE, \
                 TYPE_I440FX_PCI_DEVICE);
}

static void pc_machine__class_init(ObjectClass *oc, void *data)
{
        MachineClass *mc = MACHINE_CLASS(oc);
        pc_i440fx_7_1_machine_options(mc);
        mc->init = pc_init_v7_1;
}
static const TypeInfo pc_machine_type_v7_1 = {
        .name       = "pc-i440fx-7.1" TYPE_MACHINE_SUFFIX,
        .parent     = TYPE_PC_MACHINE,
        .class_init = pc_machine_v7_1_class_init,
};
static void pc_machine_init_v7_1(void)
{
        type_register(&pc_machine_type_v7_1);
}
type_init(pc_machine_init_v7_1)

DEFINE_I440FX_MACHINE 매크로는 새로운 유형을 정의하는 모든 작업을 직접 완료하는 것을 볼 수 있습니다. 버전 7.1에서는 새로운 TypeInfo "pc-i440fx-7.1-machine"을 정의합니다.

이것을 보고 일부 독자들은 "pc-i440fx-7.1-머신"이 어떻게 생겼는지 의문을 가질 수도 있습니다. 또한 TypeInfo의 개체는 분명히 pc_machine_type_v7_1인데 어떻게 말해야 할까요? 사실 이해하기 어렵지 않으니 TYPE_MACHINE_SUFFIX 매크로로 대체하면 이해가 될 것이다. TYPE_MACHINE_SUFFIX의 정의는 다음과 같이 include/hw/boards.h에 있습니다.

#define TYPE_MACHINE_SUFFIX "-machine"

이를 TypeInfo pc_machine_type_v7_1의 이름인 "pc-i440fx-7.1-machine"으로 대체하므로 DEFINE_I440FX_MACHINE(v7_1, "pc-i440fx-7.1", NULL, pc_i440fx_7_1_machine_options)는 "pc-i4 40fx-7.1 -machine"을 정의합니다. 이 TypeInfo는 이해하기 어렵지 않습니다.

v7_1뿐만 아니라 "DEFINE_I440FX_MACHINE(v7_1, "pc-i440fx-7.1", NULL, pc_i440fx_7_1_machine_options);"과 유사한 모든 머신 유형이 QOM 유형 목록에 추가됩니다.

다음에 무슨 일이 있었는지 알고 싶다면 다음 장을 봅시다.

Supongo que te gusta

Origin blog.csdn.net/phmatthaus/article/details/132212974
Recomendado
Clasificación