对于静态加载的驱动,内核定义了诸如early_initcall、pure_initcall、core_initcall 等众多宏。就拿 core_initcall 来说,它背后其实是 __define_initcall 宏在发挥关键作用。展开来看,__define_initcall(fn, 1)(这里以 core_initcall 的参数 1 为例),经过层层解析,就像是一场奇妙的 “魔术表演”:先是定义了一个...
#define core_initcall(fn) __define_initcall(fn, 1) #define core_initcall_sync(fn) __define_initcall(fn, 1s) #define postcore_initcall(fn) __define_initcall(fn, 2) #define postcore_initcall_sync(fn) __define_initcall(fn, 2s) #define arch_initcall(fn) __define_initcall(fn, 3) #defi...
对于静态加载的驱动,内核定义了诸如 early_initcall、pure_initcall、core_initcall 等众多宏。就拿 core_initcall 来说,它背后其实是 __define_initcall 宏在发挥关键作用。展开来看,__define_initcall(fn, 1)(这里以 core_initcall 的参数 1 为例),经过层层解析,就像是一场奇妙的 “魔术表演”:先是定义了一个...
#define early_initcall(fn) __define_initcall(fn, early) #define core_initcall(fn) __define_initcall(fn, 1) #define postcore_initcall(fn) __define_initcall(fn, 2) #define arch_initcall(fn) __define_initcall(fn, 3) #define subsys_initcall(fn) __define_initcall(fn, 4) #define fs_ini...
然后接着展开:staticinitcall_t__initcall_test_init0 = test_init;这就是一个简单的变量定义。 同时声明__initcall_test_init0这个变量即使没被引用也保留符号,且将其放置在内核镜像的.initcall0.init段处。 需要注意的是,根据官方注释可以看到early_initcall(fn)只针对内置的核心代码,不能描述模块。
#definemodule_init(x) __initcall(x);#define__initcall(fn) device_initcall(fn)#definedevice_initcall(fn) __define_initcall(fn, 6) 需要注意的是,根据官方注释可以看到early_initcall(fn)只针对内置的核心代码,不能描述模块。 __define_initcall ...
VMLINUX_SYMBOL(__initcall##level##_start) = .; \ *(.initcall##level##.init) \ *(.initcall##level##s.init) \ #define INIT_CALLS \ VMLINUX_SYMBOL(__initcall_start) = .; \ *(.initcallearly.init) \ INIT_CALLS_LEVEL(0) \ ...
在Linux内核中,initcall机制分为8个等级,从0到7。等级越低,优先级越高,执行顺序越早。其中,early、rootfs等特殊等级用于表示在不同阶段的初始化任务。内核提供了相应的宏来注册不同等级的initcall函数,这些宏位于include/linux/init.h文件中。 我们常见的module_init()、subsys_init()宏,都是负责把函数加入到initc...
*_initcall()函数通常用于设置函数指针以初始化各种子系统。 do_initcalls()within Linux kernel source code包含对各种 initcall 列表的调用以及在 Linux 内核启动期间调用它们的相对顺序。 early_initcall() core_initcall() postcore_initcall() arch_initcall() ...
early_initcall(spawn_ksoftirqd); 当ksoftirqd 被创建出来以后,它就会进入自己的线程循环函数 ksoftirqd_should_run 和 run_ksoftirqd 了。不停地判断有没有软中断需要被处理。这里需要注意的一点是,软中断不仅仅只有网络软中断,还有其它类型。 //file: include/linux/interrupt.h ...