1. initcall的执行过程
start_kernel
--> rest_init();
--> kernel_thread(kernel_init); //产生一个线程
--> kernel_init
--> do_basic_setup
在init/main.c中
-
static void __init do_basic_setup(void)
-
{
-
cpuset_init_smp();
-
usermodehelper_init();
-
init_tmpfs();
-
driver_init();
-
init_irq_proc();
-
do_ctors();
-
do_initcalls(); //终于看到主角了
-
}
start_kernel
--> rest_init();
--> kernel_thread(kernel_init); //产生一个线程
--> kernel_init
--> do_basic_setup
--> do_initcalls
在init/main.c中
extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
-
static void __init do_initcalls(void)
-
{
-
initcall_t *fn;
-
for (fn = __early_initcall_end; fn < __initcall_end; fn++)
-
do_one_initcall(*fn);
-
}
那么__early_initcall_end又是从哪里来的呢?这个先放一下.
-
int __init_or_module do_one_initcall(initcall_t fn)
-
{
-
printk(KERN_INFO "fn=%p\n",fn); //自己加的打印
-
ret = fn(); //这个fn就是一个函数地址
-
}
当此处打印出c000e620时,
在System.map中查看-->c000e620 t s3c64xx_init_irq_eint
就是要执行s3c64xx_init_irq_eint这个函数了
2. initcall_start initcall_end等是从哪里来的
在arch/arm/kernel/vmlinux.lds中,有
-
437 __initcall_start = .;
-
*(.initcallearly.init)
-
__early_initcall_end = .;
-
*(.initcall0.init) *(.initcall0s.init)
-
*(.initcall1.init) *(.initcall1s.init)
-
*(.initcall2.init) *(.initcall2s.init)
-
*(.initcall3.init) *(.initcall3s.init)
-
*(.initcall4.init) *(.initcall4s.init)
-
*(.initcall5.init) *(.initcall5s. init)
-
*(.initcallrootfs.init)
-
*(.initcall6.init) *(.initcall6s.init)
-
*(.initcall7.init) *(.initcall7s.init)
-
__initcall_end = .
从上面可以看出在 __early_initcall_end与__initcall_end之间的就是所以的initcall(0-7)
3. 如何将函数放在initcall_start与initcall_end之间的?
以s3c64xx_init_irq_eint为例:
在arch/arm/mach-s3c64xx/irq-eint.c中
-
static int __init s3c64xx_init_irq_eint(void)
-
{
-
中间省略
-
return 0;
-
}
-
arch_initcall(s3c64xx_init_irq_eint); //在函数的最后有这么个宏
宏的定义在include/linux/init.h中
-
#define pure_initcall(fn) __define_initcall("0",fn,0)
-
-
#define core_initcall(fn) __define_initcall("1",fn,1)
-
#define core_initcall_sync(fn) __define_initcall("1s",fn,1s)
-
#define postcore_initcall(fn) __define_initcall("2",fn,2)
-
#define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s)
-
#define arch_initcall(fn) __define_initcall("3",fn,3)
-
#define arch_initcall_sync(fn) __define_initcall("3s",fn,3s)
-
#define subsys_initcall(fn) __define_initcall("4",fn,4)
-
#define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s)
-
#define fs_initcall(fn) __define_initcall("5",fn,5)
-
#define fs_initcall_sync(fn) __define_initcall("5s",fn,5s)
-
#define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs)
-
#define device_initcall(fn) __define_initcall("6",fn,6)
-
#define device_initcall_sync(fn) __define_initcall("6s",fn,6s)
-
#define late_initcall(fn) __define_initcall("7",fn,7)
-
#define late_initcall_sync(fn) __define_initcall("7s",fn,7s)
-
-
#define __initcall(fn) device_initcall(fn)
又一个宏:
-
#define __define_initcall(level,fn,id) \
-
static initcall_t __initcall_##fn##id __used \
-
__attribute__((__section__(".initcall" level ".init"))) = fn
将arch_initcall
(s3c64xx_init_irq_eint
);展开后:
static initcall_t __initcall_s3c64xx_init_irq_eint3 __used __attribute__((__section__(".initcall" 3 ".init"))) = s3c64xx_init_irq_eint
就是把s3c64xx_init_irq_eint
这个函数放在了.initcall3.init这个section中
注意:这个MODULE宏很奇怪
这里的MODULE都是没有定义的,但是编译出ko来用insmode加载时,MODULE都是定义的
阅读(1771) | 评论(0) | 转发(0) |