博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用__attribute__((section()))构建初始化函数表【转】
阅读量:6168 次
发布时间:2019-06-21

本文共 1648 字,大约阅读时间需要 5 分钟。

 转自:

原创 2018-01-11 廖威雄

本文详细讲解了利用__attribute__((section()))构建初始化函数表,以及Linux内核各级初始化的原理。

 

作者简介:

    廖威雄,2016年本科毕业于暨南大学,目前就职于珠海全志科技股份有限公司从事linux嵌入式系统(Tina Linux)的开发,主要负责文件系统和存储的开发和维护,兼顾linux测试系统的设计和持续集成的维护。

    拆书帮珠海百岛分舵的组织长老,二级拆书家,热爱学习,热爱分享。

欢迎投稿:

2018年给Linuxer投稿原创Linux技术文章,一经录取,赠送人民邮电出版社任意在售图书,获得读者红包打赏,和公众号站长宋宝华200元微信红包。

 

欢迎关注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数据段中2.       main在执行初始化时并不需要知道有什么模块需要初始化,只需要把name数据段中的所有初始化接口执行一遍即可 首先: gcc -c  test.c -o test.o此时编译过程中处理了__atribute__((section(XXX))),把标记的变量/函数放到了test.o的XXX的数据段,可用 readelf命令查询。最后:ld -T 
test.o -otest.bin链接时,test.o的XXX数据段(输入段),最终保存在test.bin的XXX数据段(输出段),如此在bin中构建了初始化函数表。由于自定义了一个数据段,而默认链接脚本缺少自定义的数据段的声明,因此并不能使用默认的链接脚本。ld链接命令有两个关键的选项:ld -T

 

 

3.      编译

执行:gcc -c section.c -o section.o 编译应用源码。

执行:readelf -S section.o 查看段信息,截图如下:

 

可以看到,段[6]是我们自定义的数据段

4.      链接

执行:gcc -T ldscript.lds section.o -o section 链接成可执行的bin文件

执行:readelf -S section 查看bin文件的段分布情况,部分截图如下:

在我链接成的可执行bin中,在[25]段中存在我们自定义的段

5.      执行

执行结果:

本文后面跟着的一篇文章是关于这篇文章对应的高清思维导图。

【作者】
【出处】
【博客园】
【新浪博客】
【知乎】
【我的作品---旋转倒立摆】
【我的作品---自平衡自动循迹车】
【新浪微博】 张昺华--sky
【twitter】 @sky2030_
【facebook】 张昺华 zhangbinghua
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
你可能感兴趣的文章
如何发现“利用DNS放大攻击”的服务器
查看>>
《Arduino开发实战指南:LabVIEW卷》——第2章 Arduino软件
查看>>
京津冀大数据走廊起笔谋篇
查看>>
WIFI连网一“吻”通 黑科技让无线路由器更智能
查看>>
Ovum光器件首席分析师:硅光子不是唯一解决方案
查看>>
大数据发展进入快车道 未来会呈现高速增长
查看>>
JVM基础:JVM内存组成及分配
查看>>
数据库锁和数据库隔离级别
查看>>
Linux下的内核测试工具——perf使用简介
查看>>
《从问题到程序:用Python学编程和计算》——2.3 内置函数和数学函数包
查看>>
《Photoshop修饰与合成专业技法》目录—导读
查看>>
《Metasploit渗透测试手册》—第1章1.10节分析数据库中存储的渗透测试结果
查看>>
《Adobe Acrobat XI经典教程》—第2课减小文件大小
查看>>
《数据库技术原理与应用教程》一第2章 数据库的基础知识
查看>>
QuaggaJS —— 纯 JavaScript 开发的条形码扫描
查看>>
在图片中加入噪点就能骗过 Google 最顶尖的图像识别 AI
查看>>
免费下载!业界首部安卓热修复宝典出炉,阿里技术大牛联袂推荐
查看>>
OpenID 关联认证提供 CoreOS dex
查看>>
《Node.js区块链开发》一2.2 信用,决定着利益转移的方向
查看>>
Speedy:来自京东的 Docker 镜像存储系统
查看>>