Overview
MACHINE_START(xxxxx)
.map_io = xxx,
.reserve = xxx,
.init_irq = xxx,
.handle_irq = xxx,
.timer = xxx,
.init_machine = xxx,
.init_early = xxx,
.init_very_early = xxx,
.restart = xxx,
MACHINE_END
Calling sequence
MACHINE_START
Defined in :
arch/arm/include/asm/mach/arch.h
Calling sequence
init_machine
start_kernel()--->setup_arch()
--->rest_init--->kernel_init(){kernel_thread}
--->do_basic_setup--->
--->do_initcalls()
--->customize_machine(){__initcall3_start}--->.init_machine
start_kernel()
/init/main.c
setup_arch()
/arch/arm/kernel/setup.c
void __init setup_arch(char **cmdline_p)
{
struct machine_desc *mdesc;
setup_processor();
mdesc = setup_machine_fdt(__atags_pointer);
if (!mdesc)
mdesc = setup_machine_tags(machine_arch_type);
machine_desc = mdesc;
machine_name = mdesc->name;
- setup_machine_fdt
- setup_machine_fdt - Machine setup when an dtb was passed to the kernel
- @dt_phys: physical address of dt blob *
- If a dtb was passed to the kernel in r2, then use it to choose the
- correct machine_desc and to setup the system. */
customize_machine
static int __init customize_machine(void) { /* customizes platform devices, or adds new ones */ if (machine_desc->init_machine) machine_desc->init_machine(); return 0; } arch\_initcall(customize_machine); #define arch_initcall(fn) __define_initcall("3",fn,3) #define __define_initcall(level,fn) \ static initcall_t __initcall_##fn __used \ __attribute__((__section__(".initcall" level ".init"))) = fn /* initcalls are now grouped by functionality into separate * subsections. Ordering inside the subsections is determined * by link order. * For backwards compatibility, initcall() puts the call in * the device init subsection. * * The `id' arg to __define_initcall() is needed so that multiple initcalls * can point at the same handler without causing duplicate-symbol build errors. */
do_initcalls
Main.c (init) 22012 11/26/2012 static void __init do_initcalls(void) { int level; for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) do_initcall_level(level); }
init_early
start_kernel()--->setup_arch()--->init_very_early()
called in
/arch/arm/kernel/setup.c
void __init setup_arch(char **cmdline_p)
{
struct machine_desc *mdesc;
setup_processor();
mdesc = setup_machine_fdt(__atags_pointer);
if (!mdesc)
mdesc = setup_machine_tags(machine_arch_type);
machine_desc = mdesc;
machine_name = mdesc->name;
setup_dma_zone(mdesc);
if (mdesc->restart_mode)
reboot_setup(&mdesc->restart_mode);
if (mdesc->init_very_early)
mdesc->init_very_early();
sanity_check_meminfo();
arm_memblock_init(&meminfo, mdesc);
paging_init(mdesc);
request_standard_resources(mdesc);
if (mdesc->restart)
arm_pm_restart = mdesc->restart;
#ifdef CONFIG_MULTI_IRQ_HANDLER
handle_arch_irq = mdesc->handle_irq;
#endif
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE)
conswitchp = &dummy_con;
#endif
#endif
if (mdesc->init_early)
mdesc->init_early();
}
init_very_early
start_kernel()--->setup_arch()--->init_very_early()--->init_early()->
.reserve
start_kernel()--->setup_arch()
--->init_very_early()
--->arm_memblock_init->reserve
--->paging_init->devicemaps_init->mdesc->map_io
--->restart[mdesc->]
--->handle_irq[mdesc->]
--->init_early[mdesc->]
__init
definition
#define __init __section(.init.text) __cold notrace
#define __initdata __section(.init.data)
#define __initconst __section(.init.rodata)
#define __exitdata __section(.exit.data)
#define __exit_call __used __section(.exitcall.exit)
These macros are used to mark some functions or initialized data (doesn't apply to uninitialized data) as `initialization' functions.
The kernel can take this as hint that the function is used only during the initialization phase and free up used memory resources after.
Usage
For functions:
You should add __init immediately before the function name, like:
*
* static void __init initme(int x, int y)
* {
* extern int z; z = x * y;
* }
*
If the function has a prototype somewhere, you can also add __init between closing brace of the prototype and semicolon:
* extern int initialize_foobar_device(int, int, int) __init;
For initialized data:
You should insert __initdata between the variable name and equal sign followed by value, e.g.:
*
* static int init_variable __initdata = 0;
* static const char linux_logo[] __initconst = { 0x32, 0x36, ... };
*
- Don't forget to initialize data not at file scope, i.e. within a function,
- as gcc otherwise puts the data into the bss section and not into the init
- section.
- Also note, that this data cannot be "const".
Reference