内核module初始化与退出函数分析

module_init(my_init_function);

module_exit(my_exit_function);

首先分析这两个宏:

#define __used			__attribute__((__used__))
#define LTO_REFERENCE_INITCALL(x) \
	; /* yes this is needed */			\
	static __used __exit void *reference_##x(void)	\
	{						\
		return &x;				\
	}
#define __define_initcall(fn, id) \
	static initcall_t __initcall_##fn##id __used \
	__attribute__((__section__(".initcall" #id ".init"))) = fn; \
	LTO_REFERENCE_INITCALL(__initcall_##fn##id)
#define device_initcall(fn)		__define_initcall(fn, 6)
#define __initcall(fn) device_initcall(fn)
#define module_init(x)	__initcall(x);

# define __section(S) __attribute__ ((__section__(#S)))
#define __exit_call	__used __section(.exitcall.exit)
#define __exitcall(fn) \
	static exitcall_t __exitcall_##fn __exit_call = fn
#define module_exit(x)	__exitcall(x);

LTO_REFERENCE_INITCALL用于解决一个 LTO gcc 的问题:当一个模块中的变量没有被引用时,它将被移到程序的末尾。这会导致内核不喜欢的初始化调用的重新排序。添加一个虚拟引用函数来避免这种情况。该函数会被链接器删除。

展开主要的部分可以得到:

static initcall_t __initcall_my_init_function6 __attribute__((__used__))
	__attribute__((__section__(".initcall6.init"))) = my_init_function;


static exitcall_t __exitcall_my_exit_function __attribute__((__used__))
    __attribute__((__section__(".exitcall.exit"))) = my_init_function;
  • static initcall_t __initcall_my_init_function6: 定义了一个静态变量 __initcall_my_init_function6,其类型为 initcall_t
  • __used: 这是一个编译器指令或属性,用来告诉编译器强制使用(或者不要优化掉)标记了 __used 的变量或函数。
  • __attribute__((__section__(".initcall6.init"))): 这是一个 GCC/Clang 特有的语法,用来指定变量应该放置在哪个特定的段(section)。在这里,.initcall6.init 可能是一个自定义的段名,用来存放初始化函数。数字 6 可能表示了函数的优先级或者顺序。
  • = my_init_function;: 这部分初始化了 __initcall_my_init_function6,将其初始化为 my_init_function 函数的值。
  • __exitcall_my_exit_function的解释同上理解
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值