【问题标题】:Linux: Compiling a kernel device driver in standalone fashionLinux:以独立方式编译内核设备驱动程序
【发布时间】:2015-06-01 20:33:48
【问题描述】:

我正在为 ARM 板编译 linux。我需要对内核存储库中现有的驱动程序代码进行一些自定义更改并重新加载驱动程序。

我希望在制作后在驱动程序目录中找到一个“.ko”文件,但不存在这样的文件。显然 uImage/设备树图像编译不能那样工作。

我是否需要编写自己的 Makefile 来编译独立的设备驱动程序?

这可能是一个愚蠢的问题,但很抱歉我对内核/设备驱动程序很陌生。

编辑: 我遵循此处概述的过程:http://odroid.com/dokuwiki/doku.php?id=en:c1_building_kernel 在 git checkout 并安装交叉编译器(arm-linux-gnueabihf-gcc 4.9.2)之后,我发出了基本的 make 命令

$ make odroidc_defconfig
$ make -j4
$ make -j4 modules
$ make uImage

所有步骤都成功。日志的最后几行看起来像

KSYM    .tmp_kallsyms1.o
KSYM    .tmp_kallsyms2.o
LD      vmlinux
SORTEX  vmlinux
SYSMAP  System.map
OBJCOPY arch/arm/boot/ccImage
Kernel: arch/arm/boot/ccImage is ready
Image arch/arm/boot/ccImage.lzo is ready
UIMAGE  arch/arm/boot/uImage
Image Name:   Linux-3.10.72
Created:      Sat Mar 28 22:44:45 2015
Image Type:   ARM Linux Kernel Image (lzo compressed)
Data Size:    5459649 Bytes = 5331.69 kB = 5.21 MB
Load Address: 00208000
Entry Point:  00208000
Image arch/arm/boot/uImage is ready

编辑 2:驱动程序代码的路径 https://github.com/hardkernel/linux/tree/odroidc-3.10.y/drivers/amlogic/efuse

【问题讨论】:

  • 我假设您想说“但不存在这样的文件”。你发出了什么命令来构建内核对象?输出是什么?
  • 同意想知道构建过程和输出是什么,此外,您的构建系统是否可能配置为将输出转储到树外的某个地方?您可以尝试使用 find somepath -name "*.ko" 还要确保模块源目录中的 Makefile 已启用感兴趣的模块,无论是永久启用还是通过启用的配置选项。如果您真的不确定,请在源代码中添加 #error 或其他内容,然后查看构建是否中断 - 如果没有,则说明您的源代码没有被处理。
  • @mcleod_ideafix - 添加编译信息
  • @ChrisStratton - 执行find . -name "*.ko" 为我提供了“ko”文件列表,但没有我感兴趣的驱动程序。并且该驱动程序确实被编译(例如。添加语法错误中止汇编)
  • 显示相关驱动程序的 Makefile,或者更好的深度链接到它所在的源代码树。您确定它应该作为一个模块构建,而不是静态链接到内核吗?显示它所依赖的任何配置选项的状态。

标签: linux linux-kernel linux-device-driver


【解决方案1】:

检查你的 Makefile

#                             
# Makefile for eFuse.         
#                             

obj-$(CONFIG_EFUSE) += efuse_bch_8.o efuse_version.o efuse_hw.o efuse.o 

我们了解到代码可以构建为可加载模块,也可以永久链接到内核本身。

从我们发现的您的说明中提到的分支 odroidc-3.10.y-android 中检查 odroidc_defconfig

#
# EFUSE Support
#
CONFIG_EFUSE=y

带有“y”表示代码要链接到驱动程序中。如果它改为“m”,它将被构建为一个模块。

您可以在内核配置中更改它,但如果在需要之前没有任何设置来加载模块,它也可能会导致问题。

很可能只需安装新构建的内核并在其中链接代码(即,忘记模块的想法)就可以了。

【讨论】:

  • 许多其他驱动程序都依赖于 efuse,例如。以太网(来自 efuse 内存的 MAC 地址)。所以每当我更改驱动程序时,我总是必须更新内核映像?
【解决方案2】:

不确定您是否仍在寻找此问题的答案。

但是查看代码中的 Kconfig 文件,显示 -

    config EFUSE 
        bool "EFUSE Driver" 

并且由于您的所有驱动程序文件都是使用此配置编译的,因此上述配置描述允许 CONFIG_EFUSE 为“n”或“y”。所以你只能用这个构建静态模块(内置)。

您只需将以上描述更改为:

    config EFUSE 
        **tristate** "EFUSE Driver" 

并将 Kconfig 中的其他配置更改为三态。 一旦您在内核配置中选择驱动程序为“M”,这将允许您的驱动程序编译为模块。然后应该可以看到驱动对应的“.ko”文件了。

还要确保在将驱动程序构建为模块时使用 EXPORT_SYMBOL(foo),以便在加载模块符号时处理任何依赖关系。

【讨论】:

  • 将其转换为三态会影响加载驱动程序的顺序吗?许多其他驱动程序依赖于 efuse 驱动程序(例如以太网),如果以太网在 efuse 之前加载,它将停止运行。
  • 在转换为 tristate 时,您应该注意依赖关系。假设您想将 EFUSE 编译为“M”,那么您应该注意依赖于此的驱动程序。如果以太网被编译为静态('Y'),那么在链接期间编译器可能会抛出丢失符号的错误。在引导期间,在加载 EFUSE 之前不应探测以太网(理想情况下),尽管我需要查看代码一次。因此,一旦您使用 insmod 或其他方式加载 EFUSE,那么以太网也应该被探测到,并且如果我没记错的话,它应该可以按预期工作。
猜你喜欢
  • 1970-01-01
  • 2018-05-23
  • 2017-03-02
  • 1970-01-01
  • 2021-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多