【Linux】【开发】Linux module名和C语言文件名相同导致的编译问题

发布时间:2024年01月09日
  • 🐚作者简介:花神庙码农(专注于Linux、WLAN、TCP/IP、Python等技术方向)
  • 🐳博客主页:花神庙码农 ,地址:https://blog.csdn.net/qxhgd
  • 🌐系列专栏:Linux技术
  • 📰如觉得博主文章写的不错或对你有所帮助的话,还望大家三连支持一下呀!!! 👉关注?、点赞👍、收藏📂、评论。
  • 如需转载请参考转载须知!!

Linux module名和C语言文件名相同导致的问题

问题

  • 在基于openwrt的某系统上,编译一个内核模块my_ko,makefile内容如下:
MODULE_NAME = my_ko
$(MODULE_NAME)-y          += my_ko.o
$(MODULE_NAME)-y          += my_proc.o
obj-m := $(MODULE_NAME).o
  • 编译时报错,提示my_ko.ko中的init_func找不到。
ERROR: "xxx_func" [..../my_ko.ko] undefined!                                                                                

分析

  • 这种报错,一般表示编译模块在引用外部符号表时,没有找到指定的符号表,用到的函数找不到。但实际上,my_ko.c文件中的确定义了xxx_func函数,并且未使用任何宏控制。
    – 1、首先,通过find命令确认,my_ko.o的确生成了。
    – 2、其次,通过readelf命令,确认xxx_func的状态为UND(UND的含义是本目标文件未定义):
readelf -a my_ko.o | grep xxx_func
  170: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND xxx_func            

– 3、接着,在my_ko.c中随便新增了一个函数,toy_func,但是通过readelf命令发现,并没有这个符号。在my_ko.c中,增加了明显的编译错误,结果正常生成了my_ko.o。

  • 综上,可得到以下结论:生成的my_ko.o与my_ko.c并不对应,或者说, my_ko.o并不是由my_ko.c生成的。
  • 此外,通过查看.my_ko.cmd文件来看下实际的编译命令,发现在.my_ko.cmd中,没有任何gcc命令,说明gcc是上层统一执行的。
cmd_my_ko.o := arm-xxx-linux-xxx-ld -EL   -r -o my_ko.o

– 而对比以前其他编译正常的文件:

cmd_my_ko.o :=  arm-xxx-linux-xxx-gcc  -c -o my_ko.o my_ko.c
  • 因此,推测,在该编译框架下,并没有建立my_ko.o和my_ko.c的联系,而由于my_ko.c和模块名称相同,导致编译系统自行根据模块名,生成了模块对应的.o,覆盖了原来的.c所对应的.o。这点从其他模块处得到了证实,其他模块也生成了模块名对应的.o文件,但是实际上并没有对应的.c文件。

解决

  • 将模块名修改为不同于my_ko的名称后,问题得到解决。

TODO

  • Linux内核中,obj-m的模块名是和对应源文件名相同的,估计openwrt对此做了改造。
  • 关于为何生成内核模块名对应的.o,还要研究下openwrt的编译框架。有知道的可以在下方留言。

如本文对你有些许帮助,欢迎大佬支持我一下,您的支持是我持续创作的不竭动力
支持我的方式

文章来源:https://blog.csdn.net/qxhgd/article/details/135483706
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。