专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
嵌入式
由module_init()宏想到的
2019-07-13 06:32
发布
生成海报
站内文章
/
嵌入式Linux
13832
0
967
一,前言
在开发嵌入式Linux驱动程序时,我们通常使用module_init及module_exit宏来指定一个驱动程序的入口函数和出口函数。如果驱动模块被编译并链接至内核中,内核启动的过程中会自动加载它。通过对这两个宏定义的分析,可以写出一个简化的间接地调用函数的例子,其基本的方法是通过GNU GCC支持的__attribute__扩展功能将与入口函数地址链接至ELF文件中的特定的段区,并使用链接脚本导出该段区的地址,这样就可以做到间接调用函数了。这可以视为使用C语言开发软件,模块化的一个高级方法。
二,GNU GCC的链接脚本
GNU binutils的文档中指出,链接器ld中内嵌了一个默认的链接脚本,使用--version参数可以输出该脚本,我们把它保存到internal-ldscript.ld:
在修改这个链接脚本之前,我们要确定如何修改它;而在此之前,来让我们先编写一个用于测试的C代码。
三,使用__attribute__将函数地址信息指定到特定的段区
编写的测试代码如下:
从图中可以看到,在main函数中没有直接地调用simple_add和simple_mul这两个函数,而是访问了两个外部的结构体符号,即mfunc_info_start和mfunc_info_end,请注意这两个是“符号”,而不是指针(指针是变量,它们两个不是变量);同时,包含simple_add和simple_mul的函数地址和名称的结构体被指定到了.data.mfunc段区。
四,修改链接脚本
上图C代码中引用的两个符号mfunc_info_start和mfunc_info_end需要在链接脚本中导出,修改后的链接脚本为modified.ld,改动如下:
至此,接下来我们就可以来编译了。
五,编译并测试
编译时需要指定链接脚本:
从图中可以看到,这样间接地调用函数是可行的。当然,Linux驱动开发使用的宏比这个要复杂得多,还要解决一些模块加载次序、依赖关系等,这就需要更深入的探究了。
Ta的文章
更多
>>
由module_init()宏想到的
0 个评论
热门文章
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮