Full analysis of QEMU source code 37 - Machine (7)

Continued from the previous article: Full Analysis of QEMU Source Code 36 —— Machine (6)

References for the content of this article:

"Interesting Talk about Linux Operating System " —— Liu Chao, Geek Time

" QEMU /KVM" source code analysis and application - Li Qiang, Machinery Industry Press

Thank you very much!

The last book finished the first step select_machine function in the qemu_create_machine function. This article explains the second step function: MACHINE. In order to facilitate understanding, the qemu_create_machine function code is posted again, in softmmu/vl.c, as follows:

static void qemu_create_machine(QDict *qdict)
{
    MachineClass *machine_class = select_machine(qdict, &error_fatal);
    object_set_machine_compat_props(machine_class->compat_props);
 
    current_machine = MACHINE(object_new_with_class(OBJECT_CLASS(machine_class)));
    object_property_add_child(object_get_root(), "machine",
                              OBJECT(current_machine));
    object_property_add_child(container_get(OBJECT(current_machine),
                                            "/unattached"),
                              "sysbus", OBJECT(sysbus_get_default()));
 
    if (machine_class->minimum_page_bits) {
        if (!set_preferred_target_page_bits(machine_class->minimum_page_bits)) {
            /* This would be a board error: specifying a minimum smaller than
             * a target's compile-time fixed setting.
             */
            g_assert_not_reached();
        }
    }
 
    cpu_exec_init_all();
    page_size_init();
 
    if (machine_class->hw_version) {
        qemu_set_hw_version(machine_class->hw_version);
    }
 
    /*
     * Get the default machine options from the machine if it is not already
     * specified either by the configuration file or by the command line.
     */
    if (machine_class->default_machine_opts) {
        QDict *default_opts =
            keyval_parse(machine_class->default_machine_opts, NULL, NULL,
                         &error_abort);
        qemu_apply_legacy_machine_options(default_opts);
        object_set_properties_from_keyval(OBJECT(current_machine), default_opts,
                                          false, &error_abort);
        qobject_unref(default_opts);
    }
}

The code snippet of step 2 is as follows:

current_machine = MACHINE(object_new_with_class(OBJECT_CLASS(machine_class)));

The author didn't pay attention to this MACHINE at first, thinking that he could find it by searching in the root directory of the QEMU source code, but after searching for a long time, he couldn't find where it was defined. Later, I searched the system directory, and suspected that it was in the header file in the system directory instead of the QEMU source code, but I couldn't find it. I searched the Internet again, but there was no relevant result. In the reference books and training materials, only the above codes are listed, and no specific definitions are mentioned...

After many twists and turns, I finally found some clues. The author searches for "X86_MACHINE" on google, and one of the result links gives (points to) the old version source code of include/hw/i386/x86.h in the QEMU source code. In the source code of this old version, the definition of X86_MACHINE can be found, as follows:

From this, it is associated that since the definition of X86_MACHINE and the X86MachineState structure are in the same file (include/hw/i386/x86.h), then the definition of MACHINE should be in the same file as MachineState. So search for "MachineState" in the root directory of the QEMU source code, and finally locate the include/hw/boards.h file.

And because the content of the include/hw/i386/x86.h file where the X86_MACHINE macro is defined is different from the above due to the version update, so through the place where the original X86_MACHINE macro is defined, see what the corresponding code in the new version is. As a result, this piece of code was found:

#define TYPE_X86_MACHINE   MACHINE_TYPE_NAME("x86")
OBJECT_DECLARE_TYPE(X86MachineState, X86MachineClass, X86_MACHINE)

It can be clearly seen that the original code "#define X86_MACHINE(obj) OBJECT_CHECK(X86MachineState, (obj), TYPE_X86_MACHINE)" has become "OBJECT_DECLARE_TYPE(X86MachineState, X86MachineClass, X86_MACHINE)" in the new version . Correspondingly, in the include/hw/boards.h file, if you can also find this "OBJECT_DECLARE_TYPE" keyword, then the code corresponding to it must be the definition of MACHINE.

According to this idea, I searched in include/hw/boards.h, and as expected, I found the following code:

OBJECT_DECLARE_TYPE(MachineState, MachineClass, MACHINE)

Then there is no doubt that this code must contain the definition of MACHINE (especially the MACHINE keyword has been seen). After all the twists and turns, I finally found the MACHINE macro that was deeply hidden by the new version code by using the reasoning method!

The OBJECT_DECLARE_TYPE macro "hidden" by MACHINE will be analyzed in detail in the next chapter.

Guess you like

Origin blog.csdn.net/phmatthaus/article/details/132270129