在内核里经常可以看到__init, __devinit这样的语句,这都是在init.h中定义的宏, gcc在编译时会把被修饰的内容放到这些宏所代表的section中。
#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)
其典型用法如下:
static int __init xxx_drv_init(void)
{
return pci_register_driver(&xxx_driver);
}
之所以加入这样的宏,原因有两个
1、一部分内核初始化机制依赖它。如kernel将初始化要执行的init函数,分为7个级别,core_initcall, postcore_initcall, arch_initcall, subsys_initcall, fs_initcall, device_initcall, late_initcall。这7个级别优行列级递减,即先执行core_initcall,最后执行late_initcall。通过使用文中提到的宏, gcc会将初始化代码按下面结构安排。
在内核初始化时,从__initcall_start到__initcall_end之间的initcall被执行一次。
2、提高系统效率
初始化代码的特点是:在系统启动时运行,且一旦运行马上退出内存,不再占用内存。