Linux initcall的实现
来源:百度文库 编辑:神马文学网 时间:2024/04/28 20:46:34
initcall是内核提供的一种挂接机制,利用这种机制可以让内核在特定的
时刻调用自己,例如,某些驱动程序就有这种需要
0,相关设施
typedef int (*initcall_t)(void);
#define __define_initcall(level,fn,id) \
static initcall_t __initcall_##fn##id __attribute_used__ \
__attribute__((__section__(".initcall" level ".init"))) = fn
level的合理取值为0-7,0s-7s(2.6.19.2)
数值小的将排在前面,相同数值的s排在非s后面
/*
* 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,1)
#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 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)
内核调用链
start_kernel -> rest_init -> init -> do_basic_setup -> do_initcalls
1,所有可以initcall的函数都必须符合下面形式
int foo(void);
2,__define_initcall宏导出函数到内核映像的.initcalln.init段
__define_initcall("1",foo,1)或
core_initcall(foo)
展开后形成如下申明
static initcall_t __initcall_foo1 __attribute_used__
__attribute__((__section__(".initcall1.init"))) = foo;
所有的申明形成一个initcall_t数组
3,内核在do_initcalls函数中历遍该数组
static void __init do_initcalls(void)
{
...
for (call = __initcall_start; call < __initcall_end; call++) {
...
//对启动参数initcall_debug的支持
if (initcall_debug) {
printk("Calling initcall 0x%p", *call);
print_fn_descriptor_symbol(": %s()",
(unsigned long) *call);
printk("\n");
}
result = (*call)();
...
}
}
4,驱动中用到的重要申明module_init(x)实际就是initcall的特化:
#define module_init(x) __initcall(x);
#define __initcall(fn) device_initcall(fn)
#define device_initcall(fn) __define_initcall("6",fn,6)
时刻调用自己,例如,某些驱动程序就有这种需要
0,相关设施
typedef int (*initcall_t)(void);
#define __define_initcall(level,fn,id) \
static initcall_t __initcall_##fn##id __attribute_used__ \
__attribute__((__section__(".initcall" level ".init"))) = fn
level的合理取值为0-7,0s-7s(2.6.19.2)
数值小的将排在前面,相同数值的s排在非s后面
/*
* 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,1)
#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 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)
内核调用链
start_kernel -> rest_init -> init -> do_basic_setup -> do_initcalls
1,所有可以initcall的函数都必须符合下面形式
int foo(void);
2,__define_initcall宏导出函数到内核映像的.initcalln.init段
__define_initcall("1",foo,1)或
core_initcall(foo)
展开后形成如下申明
static initcall_t __initcall_foo1 __attribute_used__
__attribute__((__section__(".initcall1.init"))) = foo;
所有的申明形成一个initcall_t数组
3,内核在do_initcalls函数中历遍该数组
static void __init do_initcalls(void)
{
...
for (call = __initcall_start; call < __initcall_end; call++) {
...
//对启动参数initcall_debug的支持
if (initcall_debug) {
printk("Calling initcall 0x%p", *call);
print_fn_descriptor_symbol(": %s()",
(unsigned long) *call);
printk("\n");
}
result = (*call)();
...
}
}
4,驱动中用到的重要申明module_init(x)实际就是initcall的特化:
#define module_init(x) __initcall(x);
#define __initcall(fn) device_initcall(fn)
#define device_initcall(fn) __define_initcall("6",fn,6)
Linux initcall的实现
分析kernel的initcall函数 - Linux Kernel
基于Linux的视频点播系统的实现
Linux下Sniffer程序的实现
Linux串口上网的简单实现
Linux中定时器的实现算法
Linux集群系统的设计实现介绍
Linux串口上网的简单实现
ARM linux系统调用的实现原理
linux下arp攻击的实现
基于 Qmail 的 Linux 企业邮件系统的实现
嵌入式Linux的GDB远程调试的实现
基于Linux 及Tcl / Tk 的数控系统人机界面的实现
Linux 下实现网卡高可用性的几种方法
基于Linux环境下的Sniffer设计与实现
Linux利用Crontab实现对Oracle数据库的定时备份
linux forward的实现 - Kernel and Driver - CUDev
Windows与VMware下的Linux文件如何实现共享
Linux-Netfilter&iptables实现机制的分析及应用
嵌入式Linux下NAND存储系统的设计与实现hxy
Linux 系统下双机HA的功能实现
Linux中定时器的实现算法 -- Linux内核分析 -- EDN电子设计技术
linux 线程实现机制分析
Linux 线程实现机制分析