android源码分析--从logger内核驱动开始

logger的驱动程序为文件logger.c, 位于内核driver/staging/android目录.

从最后一行device_initcall(logger_init)入口, 内核在启动时调用logger_init函数.

device_initcall是在内核include/linux/init.h中定义的宏, 其临近有多个如xxx_initcall的定义.根据init.h中定义, 在配置为非module的驱动中, xxx_initcall最终都是#define_initcall(level, fn, id), 其中level决定在内核启动过程中调用优先级,如下:

#define device_initcall(fn) define_initcall(“6”,fn,6)

在配置为module的驱动中, xxx_initcall定义为module_init.



#define device_initcall(fn) module_init(fn)

注意配置为非module模块时, init.h中同样定义了module_init宏, 但是有如下定义:



#define
initcall(fn) device_initcall(fn)

define module_init(x) __initcall(x)


从Kconfig配置可知, logger驱动可配置为内置模块或可卸载模块, 而binder和ashm模块只能配置为内置模块.
关于define_initcall的解释可以参考这篇文章, 或者参考linux内核分析或linux驱动开发的相关书籍.摘录修改部分内容:
宏定义
define_initcall(level,fn, id)对于内核的初始化很重要,他指示编译器在编译的时候,将一系列初始化函数的起始地址值按照一定的顺序放在一个section中。在内核初始化段,do_initcalls() 将按顺序从该section中以函数指针的形式取出这些函数的起始地址,来依次完成相应的初始化。


#define define_initcall(level,fn,id) \
static initcall_t
initcall##fn##id used \
attribute((section(“.initcall” level “.init”))) = fn其中 initcall_t 是个函数指针类型:



typedef int (*initcall_t)(void);

而属性 attribute((section())) 则表示把对象放在一个这个由括号中的名称所指代的section中。所以这个宏定义的的含义是:

1) 声明一个名称为initcall##fn##id的函数指针(其中##表示替换连接,);

2) 将这个函数指针初始化为fn;

3) 编译的时候需要把这个函数指针变量放置到名称为 “.initcall” level “.init"的section中(比如level=“1”,代表这个section的名称是 “.initcall1.init”)。

你可能感兴趣的:(android源码分析--从logger内核驱动开始)