`DT_MACHINE_START(MSM8974_DT, "Qualcomm MSM 8974 (Flattened Device Tree)")
.map_io = msm8974_map_io,
.init_irq = msm_dt_init_irq,
.init_machine = msm8974_init,
.handle_irq = gic_handle_irq,
.timer = &msm_dt_timer,
.dt_compat = msm8974_dt_match,
.reserve = msm_8974_reserve,
.init_very_early = msm8974_init_very_early,
.restart = msm_restart,
.smp = &msm8974_smp_ops,
MACHINE_END`
This DT_MACHINE_START macro is there in one of board files for a Qualcomm chipset 8974. My question is that how the control comes to this MACHINE START as ".init_machine" is getting called.
The Linux kernel creates an ARRAY using section magic and linker scripts and the boot loader must pass the key MSM8974_DT to Linux. Linux init code looks up the machine structure and calls these function pointers at appropriate times during initialization. See arch/arm/kernel/setup.c for the call location.
See similar: SO MACHINE_START macro. The current arch.h has definitions and vmlinux.lds.S has the linker section .init.arch.info
.
How is control handed to the MACHINE START's ".init_machine"?
This call is from customize_machine
in the current Linux source.
static int __init customize_machine(void)
{
/*
* customizes platform devices, or adds new ones
* On DT based machines, we fall back to populating the
* machine from the device tree, if no callback is provided,
* otherwise we would always need an init_machine callback.
*/
of_iommu_init();
if (machine_desc->init_machine)
machine_desc->init_machine(); /** HERE - calls your routine **/
#ifdef CONFIG_OF
else
of_platform_populate(NULL, of_default_bus_match_table,
NULL, NULL);
#endif
return 0;
}
The structure pointer machine_desc
is matched earlier in the init code as above.