【发布时间】:2018-05-29 01:11:37
【问题描述】:
前段时间,我为 ARMv7 (Cortex-A5) 开发了一个内核模块。该模块运行良好,但我需要为其添加一个功能。不幸的是,安装了交叉编译器工具链的机器同时被重新使用,所以我不得不重新设置它。当然,我发现我没有记录所有细节,而且我一直在努力获得一个可以实际加载的模块。大约一天后,我设法编译了目标上insmod 接受的东西。
但是模块什么也不做。
insmod 没有给我任何错误。 dmesg 没有显示任何内容,尽管该模块应该从其探测例程中打印一些信息。此外,它应该创建的字符设备不存在,显然模块的探测例程没有运行。
如果我在旧的.ko(我仍然拥有)和新的.ko 上都使用modinfo,则没有区别。 file 也显示相同的输出,除了 sha1 校验和,这是意料之中的:
module_old.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]=1f55850e8da4b3b5931536060d62193d94730cf6, not stripped
module_new.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]=c3b1f6fdcb72381beb7b8a766c70af7a1252a78f, not stripped
我看到的唯一区别是新的.ko 比旧的大了大约 10 倍:
-rw-r--r-- 1 root root 154504 Apr 21 23:38 module_new.ko
-rw-rw-r-- 1 root root 17956 Oct 4 2017 module_old.ko
我的Makefile如下:
obj-m += mymodule.o
KERNEL_SOURCE_DIR = /home/ludo/linux-at91-linux4sam_5.3
all:
make -C $(KERNEL_SOURCE_DIR) CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm M=$(PWD) modules
clean:
make -C $(KERNEL_SOURCE_DIR) CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm M=$(PWD) clean
我尝试添加
CFLAGS_mymodule.o := -march=armv7-a -mtune=cortex-a5
但这并没有什么不同。
我正在使用 gcc 4.9 构建 Debian Jessie (8.10)。我不记得我用什么 GCC 版本构建旧版本,但它是 4.x,而不是新版本。
有什么办法可以调试这个问题吗?
【问题讨论】:
-
首先验证您启动时使用的设备树(即 /proc/device-tree/)是否确实引用了此驱动程序。见Driver code in kernel module doesn't execute?
-
我实际上还没有对驱动程序进行任何更改。所以
module_new.ko和module_old.ko来自完全相同的源文件,但是module_new.ko是使用新的交叉编译器工具链构建的(并且不起作用),而module_old.ko是使用旧工具链构建的(我没有了)。我正在使用相同的 DT 在同一块板上进行测试。工具链中一定有问题,因为这是唯一的区别...... -
变量(内置定义)将在更新编译器时发生变化。代码不相同。内核有许多非常熟悉 GCC 版本和特性的宏。众所周知,许多编译器会破坏内核。可以说这是谁的问题。然而,事实是改变编译器会改变模块代码/二进制文件。 “工具链”可能是个问题,或者您可能遇到内核/工具链兼容性问题。
-
您可以分发源代码,但通常测试编译器版本。 Kbuild/kconfig 应该正在测试您的编译器,以便标记已知的错误编译器。但是,他们通常不会测试宇宙中每个坏编译器,只测试已知的坏编译器或真正旧的编译器。由于模块不是“in-tree”,因此您可能违反了一些规则,并且由于编译器定义了受影响的事物而进行了一些更改。我只是说这是可能并且不是绝对你的问题。请记住它...
-
哦,你可能需要学习如何在Linux内核中使用调试和跟踪工具等手段。例如,命令行中的 initcall_debug 将显示哪些模块已初始化以及到目前为止的进展情况。 ignore_loglevel 允许在级别上独立查看屏幕上的所有消息。依此类推……就规模而言,您需要了解
strip的含义以及它的使用方式。
标签: gcc linux-kernel arm kernel-module