前言
在使用 platform_bus/platform_device/platform_driver 框架的时候
有时候需要编写的是 driver,那么这些与之配套的 device 都是什么时候注册进系统的呢?
注:这里针对的是未支持 dts 以前的内核
流程
系统所有的 platform_device 定义在
static struct platform_device __initdata *smdk_devs[] = {
&s3c_device_nand,
&smdk_led4,
&smdk_led5,
&smdk_led6,
&smdk_led7,
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
&s3c_device_dm9k,
#endif
#ifdef CONFIG_SERIAL_EXTEND_S3C24xx
&s3c_device_8250,
#endif
#ifdef CONFIG_TOUCHSCREEN_S3C2410
&s3c_device_ts,
#endif
};
调用流程
start_kernel(void)
setup_arch(char **cmdline_p)
mdesc = setup_machine(machine_arch_type);//获得声明的板子结构体
init_machine = mdesc->init_machine;//设置 init_machine = smdk2440_machine_init
rest_init(void)
kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
kernel_init(void * unused)
do_basic_setup(void)
do_initcalls(void)
// 遍历 __initcall_start 和 __initcall_end 之间的段中的函数,并调用
for (call = __initcall_start; call < __initcall_end; call++) {
result = (*call)();//即调用下面的函数,而他是在下面的语句中被存到 __initcall_start 和 __initcall_end 之间的段的
customize_machine(void)
if (init_machine)
init_machine(); // 这个函数即 smdk2440_machine_init,在 setup_arch 中设置
smdk2440_machine_init
// 这里也注册了一些设备,如 i2c 的平台设备
platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
smdk_machine_init
platform_add_devices// 这里面注册上面的声明的那些资源的 smdk_devs
for (i = 0; i < num; i++) {
ret = platform_device_register(devs[i]);
if (ret) {
while (--i >= 0)
platform_device_unregister(devs[i]);
break;
}
}
1.将 customize_machine 存到 __initcall_start 和 __initcall_end 之间的段中
arch_initcall(customize_machine);
#define arch_initcall(fn) __define_initcall("3",fn,3)
#define __define_initcall(level,fn,id) \
static initcall_t __initcall_##fn##id __attribute_used__ \
__attribute__((__section__(".initcall" level ".init"))) = fn
2.smdk2440_machine_init 在板子结构体内
MACHINE_START(S3C2440, "SMDK2440")
// Maintainer: Ben Dooks <[email protected]>
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
.map_io = smdk2440_map_io,
.init_machine = smdk2440_machine_init,
.timer = &s3c24xx_timer,
MACHINE_END