【问题标题】:Cross-compiled kernel module (ARM) does nothing交叉编译内核模块 (ARM) 什么都不做
【发布时间】: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.komodule_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


【解决方案1】:

我忘记记录构建过程中的一个非常重要的步骤。在构建模块之前,需要确保配置是一致的。这可以通过从内核源代码树的根目录执行来完成:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- sama5_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules

然后可以编译模块,一切都很好。

【讨论】:

    猜你喜欢
    • 2014-10-23
    • 2014-05-01
    • 1970-01-01
    • 2011-03-28
    • 2014-01-25
    • 2014-04-30
    • 2020-08-15
    • 2014-04-14
    • 1970-01-01
    相关资源
    最近更新 更多