本文详细讲解了利用__attribute__((section()))构建初始化函数表,以及Linux内核各级初始化的原理。
作者简介:
廖威雄,2016年本科毕业于暨南大学,目前就职于珠海全志科技股份有限公司从事linux嵌入式系统(Tina Linux)的开发,主要负责文件系统和存储的开发和维护,兼顾linux测试系统的设计和持续集成的维护。
拆书帮珠海百岛分舵的组织长老,二级拆书家,热爱学习,热爱分享。
欢迎投稿:
2018年给Linuxer投稿原创Linux技术文章,一经录取,赠送人民邮电出版社任意在售图书,获得读者红包打赏,和公众号站长宋宝华200元微信红包。
Linuxer-"Linux开发者自己的媒体"第五月稿件和赠书名单
欢迎关注Linuxer
问题导入
传统的应用编写时,每添加一个模块,都需要在main中添加新模块的初始化
使用__attribute__((section()))构建初始化函数表后,由模块告知main:“我要初始化“,添加新模块再也不需要在main代码中显式调用模块初始化接口。
以此实现main与模块之间的隔离,main不再关心有什么模块,模块的删减也不需要修改main。
那么,如何实现这个功能呢?如何实现DECLARE_INIT呢?联想到内核驱动,所有内核驱动的初始化函数表在哪里?为什么添加一个内核驱动不需要修改初始化函数表?
下文会从 构建初始化函数表的原理分析、分析内核module_init实现、演练练习 的3个角度给小伙伴分享。
构建初始化函数表的原理分析
__attribute__((section(”name“)))是gcc编译器支持的一个编译特性(arm编译器也支持此特性),实现在编译时把某个函数/数据放到name的数据段中。因此实现原理就很简单了:
1. 模块通过__attribute__((section("name")))的实现,在编译时把初始化的接口放到name数据段中