全球最实用的IT互联网信息网站!

AI人工智能P2P分享&下载搜索网页发布信息网站地图

当前位置:诺佳网 > 电子/半导体 > 嵌入式技术 >

printk函数的地址问题怎么解决

时间:2023-09-26 16:49

人气:

作者:admin

标签: 内核  编译  函数 

导读:不知大家有没有想过,在一个内核模块代码中,会用到 printk 函数,而这个函数不是我们实现的,它是内核代码的一部分,但我们为什么能够编译通过呢? 我们的代码之所以能够编译通...

不知大家有没有想过,在一个内核模块代码中,会用到printk函数,而这个函数不是我们实现的,它是内核代码的一部分,但我们为什么能够编译通过呢?

我们的代码之所以能够编译通过,是因为对模块的编译 仅仅是编译,并没有链接

编译出来的.ko文件是一个普通的ELF文件 ,使用file命令和nm命令,我们可以看到相关的信息:

# file vser.ko
vser.ko ELF 32-bit LSB relocatable, Intel 80386, vserion 1 (SYSV), BuildID[sha1]=0x09ca747e6f75c65v19a5da9102113v98d7cea24, not stripped
# nm vser.ko
......
00000004 d port
    U printk
00000000 t vser_exit
00000000 t vser_init

vser_initvser_exit分别是模块的入口函数和出口函数,使用nm命令查看模块目标文件的符号信息时,可以看到vser_exitvser_init的符号类型是t,表示它们是 函数

printk的 符号类型是U,表示它是一个 未决符号 。意思是说在编译阶段不知道这个符号的地址,因为它被定义在其他文件中,没有放在模块代码一起编译。

那printk函数的地址问题怎么解决呢?答案是用EXPORT_SYMBOL宏将printk导出即可。

EXPORT_SYMBOL导出符号

大致原理:利用EXPORT_SYMBOL宏生成一个特定的结构并放在ELF文件的一个特定段中,在 内核的启动过程中,会将符号的确切地址填充到这个结构的特定成员中

模块加载时,加载程序将去处理未决符号,在特殊段中搜索符号的名字,如果找到,则将获得的地址填充在被加载模块的相应段中,这样符号的地址就可以确定。

使用这种方式处理未决符号,其实相当于把链接的过程推后,进行了动态链接,和普通的应用程序使用共享库函数的道理是类似的 。可以发现,内核将会有大量的符号导出,为模块提供了丰富的基础设施。

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信