相关疑难解决方法(0)

如何从另一个模块调用导出的内核模块函数?

我正在编写一个API作为内核模块,为设备驱动程序提供各种功能.我在mycode.c中写了三个函数.然后我构建并加载了模块,然后将mycode.h复制到<kernel>/include/linux中.在设备驱动程序中,我有一个#include <linux/mycode.h>并调用这三个函数.但是当我构建驱动程序模块时,我得到三个链接器警告,说明这些函数是未定义的.

笔记:

  • 函数在mycode.h 中声明为extern
  • 使用mycode.c中的EXPORT_SYMBOL(func_name)导出函数
  • 运行命令nm mycode.ko显示符号表中可用的所有三个函数(它们旁边的大写字母T,表示符号在文本(代码)部分中找到)
  • 加载模块后,命令grep func_name/proc/kallsyms将所有三个函数显示为已加载

很明显,函数正在正确导出,内核知道它们的位置和位置.那么为什么司机不能看到他们的定义呢?知道我错过了什么吗?


编辑:我在这里找到了一些相关的信息: http ://www.kernel.org/doc/Documentation/kbuild/modules.txt

有时,外部模块使用来自另一个外部模块的导出符号.kbuild需要完全了解所有符号,以避免吐出有关未定义符号的警告.这种情况存在三种解决方案.

注意:建议使用顶级kbuild文件的方法,但在某些情况下可能不切实际.

使用顶级kbuild文件如果你有两个模块,foo.ko和bar.ko,其中foo.ko需要来自bar.ko的符号,你可以使用一个通用的顶级kbuild文件,所以这两个模块都是用同一个编译的建立.请考虑以下目录布局:

  ./foo/ <= contains foo.ko       ./bar/ <= contains bar.ko

  The top-level kbuild file would then look like:

  #./Kbuild (or ./Makefile):          obj-y := foo/ bar/

  And executing

      $ make -C $KDIR M=$PWD

  will then do the expected and compile both modules with         full
Run Code Online (Sandbox Code Playgroud)

任何一个模块的符号知识.

使用额外的Module.symvers文件构建外部模块时,会生成Module.symvers文件,其中包含未在内核中定义的所有导出符号.要从bar.ko访问符号,请将module.symvers文件从bar.ko的编译复制到构建foo.ko的目录.在模块构建期间,kbuild将读取外部模块目录中的Module.symvers文件,并且在构建完成时,将创建一个新的Module.symvers文件,其中包含已定义的所有符号的总和,而不是内核的一部分.

使用"make"变量KBUILD_EXTRA_SYMBOLS如果从另一个模块复制Module.symvers是不切实际的,则可以在构建文件中将空格分隔的文件列表分配给KBUILD_EXTRA_SYMBOLS.这些文件将在其符号表初始化期间由modpost加载.

但是对于所有这三种解决方案,为了让任何驱动程序使用我的API,它必须创建一个新的Makefile或直接访问我的Module.symvers文件?这看起来有点不方便.我希望他们能够#include我的头文件并且好好去.不存在其他替代方案吗?

c kernel module symbol-table

25
推荐指数
1
解决办法
2万
查看次数

在linux源代码中添加新的驱动程序代码

我开发了一个Linux设备驱动程序.截至目前,我正在Ubuntu 12.04上使用交叉编译器为arm编译它,然后在我的arm Linux映像中进行修改.但我想学习如何在Linux源代码中添加它,并通过配置arm Linux来添加/删除,以便我可以使用Linux源代码编译来编译它?

有任何想法吗?

linux-device-driver linux-kernel

18
推荐指数
3
解决办法
4万
查看次数

如何使用 QEMU 调试 Linux 内核模块?

我正在从事学术项目,修改一些Kernel Networking代码并包含一个新的Kernel module.

我正在使用 QEMU 加载修改后的内核并进行测试。

但是,我发现某些系统需要完整的操作系统.img才能进行调试。
没有它可能吗?

或者,这是可以与 Kernel 2.6 系统一起使用的发行版。除了运行程序的能力(包括网络支持)之外,发行版不需要具有任何功能。

linux qemu kernel-module linux-kernel

2
推荐指数
2
解决办法
9820
查看次数

如何下载 Torvalds Linux Kernel master、(重新)编译它并使用 QEMU 启动它?

几天来,我正在研究一个小项目,以探索内核编程。然而,我在网上看了很多关于内核编译的问题,并在之前问过一个问题,但我在某些时候仍然感到迷茫。

如果我需要进行一些内核编程,我认为使用 Linus Torvalds 的 Linux 源代码将是最好的起点。所以我做了以下操作(来自 MacOS High Sierra)

  • 下载内核源代码:https://github.com/torvalds/linux
  • 解压它
  • 启动终端并运行:
    • vagrant init
    • vagrant up
    • vagrant ssh
  • 连接后,我输入:
    • cd /vagrant/linux 为了进入Linux源解压文件夹
    • make menuconfig 我只是按了确定/保存
    • sudo make -j 4 && sudo make modules_install -j 4 && sudo make install -j 4

现在,我遇到了一个小错误:

agrant @vagrant-ubuntu-trusty-64:/vagrant/Kernel-Programming/linx-kernel$ sudo make -j 4 && sudo make modules_install -j 4 && sudo make install -j 4
  CHK include/config/kernel.release
CHK     include/generated/uapi/linux/version.h
CHK     include/generated/utsrelease.h
CHK     scripts/mod/devicetable-offsets.h
CHK     include/generated/timeconst.h
CHK     include/generated/bounds.h
CHK     include/generated/asm-offsets.h
CALL    scripts/checksyscalls.sh …
Run Code Online (Sandbox Code Playgroud)

linux qemu linux-kernel macos-high-sierra

1
推荐指数
1
解决办法
5152
查看次数