您的位置:首页 > 其它

about macros fs_initcall and module_init

2016-06-18 14:48 218 查看
一、macro fs_initcall,以fs_initcall(usb20_init)为例

1. fs_initcall(usb20_init) macro展开

*******************************************************************************

fs_initcall(usb20_init);

expanding:

fs_initcall(usb20_init) -->
static initcall_t __initcall_usb20_init5 __used \
__attribute__((__section__(".initcall" "5" ".init"))) = usb20_init;

*******************************************************************************

通过fs_initcall定义了一个initcall_t类型的函数指针变量,它指向usb20_init。

initcall_t函数指针类型定义:

*******************************************************************************

typedef int (*initcall_t)(void);

*******************************************************************************

2. kernel段定义

在include/asm-generic/vmlinux.lds.h中有如下macro定义:

*******************************************************************************

#define INITCALLS \
*(.initcallearly.init)
\
VMLINUX_SYMBOL(__early_initcall_end) = .;
\

  *(.initcall0.init)
\

  *(.initcall0s.init)
\

  *(.initcall1.init)
\

  *(.initcall1s.init)
\

  *(.initcall2.init)
\

  *(.initcall2s.init)
\

  *(.initcall3.init)
\

  *(.initcall3s.init)
\
*(.initcallbresume.init)
\
*(.initcallresume.init)
\

  *(.initcall4.init)
\

  *(.initcall4s.init)
\

  *(.initcall5.init)
\

  *(.initcall5s.init)
\
*(.initcallrootfs.init)
\

  *(.initcall6.init)
\

  *(.initcall6s.init)
\

  *(.initcall7.init)
\

  *(.initcall7s.init)

#define INIT_CALLS \
VMLINUX_SYMBOL(__initcall_start) = .;
\
INITCALLS
\
VMLINUX_SYMBOL(__initcall_end) = .;

INIT_CALLS是在arch/arm/kernel/vmlinux.lds.S中被引用:

*******************************************************************************
__pv_table_begin = .;
*(.pv_table)
__pv_table_end = .;

INIT_SETUP(16)

INIT_CALLS
CON_INITCALL
SECURITY_INITCALL

*******************************************************************************

所以在step1中定义的initcall_t __initcall_usb20_init5指针变量放在initcall section中的.initcall5.init子段中。

3. step1中的__initcall_usb20_init5函数调用

在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);

}

*******************************************************************************

二、macro module_init

定义在include/linux/init.h头文件中:

*******************************************************************************

#define module_init(x) __initcall(x);

#define __initcall(fn) device_initcall(fn)

#define device_initcall(fn) __define_initcall("6",fn,6)

*******************************************************************************

__define_initcall定义一个initcall_t类型的__initcall_usb20_init6指针变量放在initcall section中的.initcall6.init子段中。

*******************************************************************************

#define __define_initcall(level,fn,id) \
static initcall_t __initcall_##fn##id __used \
__attribute__((__section__(".initcall" level ".init"))) = fn

*******************************************************************************

这个和上面的fs_initcall是类似的,fs_initcall是:

#define fs_initcall(fn) __define_initcall("5",fn,5)

所以fs_initcall和module_init定义的函数指针变量都放在kernel的initcall section,只是前者是位于initcall section中的.initcall5.init子段中,

而后者位于.initcall6.init子段中。存储在initcall section(这个段中的early子段除外)中的指针函数都会在kernel初始化时的do_initcalls函数中

被调用。5子段位于前面,所以它们先被执行,6后被执行。看include/linux/init.h中的宏定义就可以看出:

*******************************************************************************

#define early_initcall(fn) __define_initcall("early",fn,early)

/*

 * A "pure" initcall has no dependencies on anything else, and purely

 * initializes variables that couldn't be statically initialized.

 *

 * This only exists for built-in code, not for modules.

 */

#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)

#ifdef CONFIG_FAST_RESUME

#define beforeresume_initcall(fn) __define_initcall("bresume",fn,bresume)

#define resume_initcall(fn) __define_initcall("resume",fn,resume)

#endif

#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)

*******************************************************************************
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: