日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Linux initcall的實現(xiàn)...

 黃浦江中的一條魚 2009-07-17
initcall是內(nèi)核提供的一種掛接機制,利用這種機制可以讓內(nèi)核在特定的
時刻調(diào)用自己,例如,某些驅(qū)動程序就有這種需要

0,相關(guān)設(shè)施
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)
數(shù)值小的將排在前面,相同數(shù)值的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)

內(nèi)核調(diào)用鏈
start_kernel -> rest_init -> init -> do_basic_setup -> do_initcalls

1,所有可以initcall的函數(shù)都必須符合下面形式
int foo(void);

2,__define_initcall宏導(dǎo)出函數(shù)到內(nèi)核映像的.initcalln.init段
__define_initcall("1",foo,1)或
core_initcall(foo)
展開后形成如下申明
static initcall_t __initcall_foo1 __attribute_used__
__attribute__((__section__(".initcall1.init"))) = foo;
所有的申明形成一個initcall_t數(shù)組

3,內(nèi)核在do_initcalls函數(shù)中歷遍該數(shù)組
static void __init do_initcalls(void)
{
...
for (call = __initcall_start; call < __initcall_end; call++) {
...
//對啟動參數(shù)initcall_debug的支持
if (initcall_debug) {
printk("Calling initcall 0x%p", *call);
print_fn_descriptor_symbol(": %s()",
(unsigned long) *call);
printk("\n");
}

result = (*call)();
...
}
}

4,驅(qū)動中用到的重要申明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)

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多