Driver modules的初始化:
start_kernel
|
rest_init
|
kernel_init
|
static void __init do_basic_setup(void)
{
/* drivers will send hotplug events */
init_workqueues();
usermodehelper_init();
driver_init();
init_irq_proc();
do_initcalls();
}
void __init driver_init(void) [drivers/base/init.c]
{
/* These are the core pieces */
devices_init(); //{devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);}
buses_init(); //{devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);}
classes_init(); //{class_kset = kset_create_and_add("class", NULL, NULL);}
firmware_init(); //{firmware_kobj = kobject_create_and_add("firmware", NULL);}
hypervisor_init(); //{hypervisor_kobj = kobject_create_and_add("hypervisor", NULL);}
/* These are also core pieces, but must come after the
* core core pieces.
*/
platform_bus_init();
system_bus_init();
cpu_dev_init();
memory_dev_init();
}
int __init platform_bus_init(void)
{
int error;
error = device_register(&platform_bus);
if (error)
return error;
error = bus_register(&platform_bus_type);
if (error)
device_unregister(&platform_bus);
return error;
}
一些宏定义, 大概记录下,有空再来详细研究:
[include/linux/init.h]
链接参照:arch/arm/kernel/vmlinux.lds.S
//下面将函数注册到.initcall section, 但将会在哪里调用呢?
#define __define_initcall(level,fn,id) \
static initcall_t __initcall_##fn##id __used \
__attribute__((__section__(".initcall" level ".init"))) = fn
#define device_initcall(fn) __define_initcall("6",fn,6)
#define __initcall(fn) device_initcall(fn)
#ifndef MODULE
#define module_init(x) __initcall(x);
#else
/* Each module must use one module_init(), or one no_module_init */
#define module_init(initfn) \
static inline initcall_t __inittest(void) \
{ return initfn; } \
int init_module(void) __attribute__((alias(#initfn)));
/* This is only required if you want to be unloadable. */
#define module_exit(exitfn) \
static inline exitcall_t __exittest(void) \
{ return exitfn; } \
void cleanup_module(void) __attribute__((alias(#exitfn)));
#endif
[/include/linux/device.h]
#define DRIVER_ATTR(_name, _mode, _show, _store) \
struct driver_attribute driver_attr_##_name = \
__ATTR(_name, _mode, _show, _store)
#define BUS_ATTR(_name, _mode, _show, _store) \
struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)
[include/linux/module.h]
#define __EXPORT_SYMBOL(sym, sec) \
extern typeof(sym) sym; \
__CRC_SYMBOL(sym, sec) \
static const char __kstrtab_##sym[] \
__attribute__((section("__ksymtab_strings"), aligned(1))) \
= MODULE_SYMBOL_PREFIX #sym; \
static const struct kernel_symbol __ksymtab_##sym \
__used \
__attribute__((section("__ksymtab" sec), unused)) \
= { (unsigned long)&sym, __kstrtab_##sym }
#define EXPORT_SYMBOL(sym) \
__EXPORT_SYMBOL(sym, "")
#define EXPORT_SYMBOL_GPL(sym) \
__EXPORT_SYMBOL(sym, "_gpl")
#define EXPORT_SYMBOL_GPL_FUTURE(sym) \
__EXPORT_SYMBOL(sym, "_gpl_future")