在 Fedora 20 中查找简单设备驱动程序的头文件
finding header files for simple device driver in Fedora 20
因此,我尝试按照简单示例加载 O'Rielly Linux 设备驱动程序手册中的 "Hello World" 设备驱动程序。问题是出于某种原因,除非我在 include 语句中明确定义我的头文件的路径,否则它不会工作;即我必须输入 #include </usr/src/kernels/3.19.8-100.fc20.i686+PAE/include/linux/init.h>
而不仅仅是 #include </linux/init.h>
这是我的 makefile
obj-m := hello.o
KDIR =/usr/src/kernels/3.19.8-100.fc20.i686+PAE/include
all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
并且它 returns 无法在所有头文件中找到错误,除非明确定义为 #include </usr/src/kernels/3.19.8-100.fc20.i686+PAE/include/linux/init.h>
我宁愿不必这样做。
感谢您的帮助。
如果它对任何人有帮助,如果我保留显式包含语句然后编译,结果 hello.mod.c 文件如下。
#include <linux/module.h>
#include <linux/vermagic.h>
#include <linux/compiler.h>
MODULE_INFO(vermagic, VERMAGIC_STRING);
__visible struct module __this_module
__attribute__((section(".gnu.linkonce.this_module"))) = {
.name = KBUILD_MODNAME,
.init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
.exit = cleanup_module,
#endif
.arch = MODULE_ARCH_INIT,
};
static const char __module_depends[]
__used
__attribute__((section(".modinfo"))) =
"depends=";
这可以使用 insmod 正常加载。
您的编译器应该有一个选项来指定包含的搜索路径。 GnuCC (gcc
, g++
) 和 CLang (clang
, clang++
) 都使用 -I
.
如果您的头文件位于 /usr/src/kernels/3.19.8-100/include/linux/init.h
并且您调用,假设 g++
使用:
g++ -I /usr/src/kernels/3.19.8-100/include/ source.cpp
那么source.cpp
可以#include <linux/init.h>
.
现在,您需要了解如何通过 OS makefile 向编译器提供该命令行选项以构建模块。这在几个地方都有记录,但通常是定义一个包含附加选项的环境变量 CPPFLAGS
:
$ export CPPFLAGS="-I /usr/src/kernels/3.19.8-100/include/"
$ make
KDIR =/usr/src/kernels/3.19.8-100.fc20.i686+PAE/include
我认为你的 "KDIR line" 是错误的....这个 Makefile 有效(通常):
obj-m := hello.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
假设 # dnf install kernel kernel-devel
→ 即kernel-devel
必须与 kernel
.
完全匹配
注意:/lib/modules/[version]/{build}/ 是 link 到 /usr/src/kernels/[version]/
, not to /usr/src/kernels/[version]/include/ .... link 是在安装 kernel-devel
时创建的
我找到了答案。感谢 YSC 为我指明了正确的道路。我只需要做一些额外的事情 Where Does GCC Look to Find its Header Files?
基本上,我需要将包含目录添加到 gcc 的 header 包含路径。我通过输入 cpp -I <desired path> -v
来做到这一点,对我来说是 /usr/src/kernels/......等
运行 刚刚 cpp -v
给了我一个包含路径 gcc 搜索的列表。只要确保它在那里。
所以现在我的 driver 模块可以正确构建并使用 include 语句作为 #include <linux/init.h>
加载,就像我想要的那样。
因此,我尝试按照简单示例加载 O'Rielly Linux 设备驱动程序手册中的 "Hello World" 设备驱动程序。问题是出于某种原因,除非我在 include 语句中明确定义我的头文件的路径,否则它不会工作;即我必须输入 #include </usr/src/kernels/3.19.8-100.fc20.i686+PAE/include/linux/init.h>
而不仅仅是 #include </linux/init.h>
这是我的 makefile
obj-m := hello.o
KDIR =/usr/src/kernels/3.19.8-100.fc20.i686+PAE/include
all:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) clean
并且它 returns 无法在所有头文件中找到错误,除非明确定义为 #include </usr/src/kernels/3.19.8-100.fc20.i686+PAE/include/linux/init.h>
我宁愿不必这样做。
感谢您的帮助。
如果它对任何人有帮助,如果我保留显式包含语句然后编译,结果 hello.mod.c 文件如下。
#include <linux/module.h>
#include <linux/vermagic.h>
#include <linux/compiler.h>
MODULE_INFO(vermagic, VERMAGIC_STRING);
__visible struct module __this_module
__attribute__((section(".gnu.linkonce.this_module"))) = {
.name = KBUILD_MODNAME,
.init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
.exit = cleanup_module,
#endif
.arch = MODULE_ARCH_INIT,
};
static const char __module_depends[]
__used
__attribute__((section(".modinfo"))) =
"depends=";
这可以使用 insmod 正常加载。
您的编译器应该有一个选项来指定包含的搜索路径。 GnuCC (gcc
, g++
) 和 CLang (clang
, clang++
) 都使用 -I
.
如果您的头文件位于 /usr/src/kernels/3.19.8-100/include/linux/init.h
并且您调用,假设 g++
使用:
g++ -I /usr/src/kernels/3.19.8-100/include/ source.cpp
那么source.cpp
可以#include <linux/init.h>
.
现在,您需要了解如何通过 OS makefile 向编译器提供该命令行选项以构建模块。这在几个地方都有记录,但通常是定义一个包含附加选项的环境变量 CPPFLAGS
:
$ export CPPFLAGS="-I /usr/src/kernels/3.19.8-100/include/"
$ make
KDIR =/usr/src/kernels/3.19.8-100.fc20.i686+PAE/include
我认为你的 "KDIR line" 是错误的....这个 Makefile 有效(通常):
obj-m := hello.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
假设 # dnf install kernel kernel-devel
→ 即kernel-devel
必须与 kernel
.
注意:/lib/modules/[version]/{build}/ 是 link 到 /usr/src/kernels/[version]/
, not to /usr/src/kernels/[version]/include/ .... link 是在安装 kernel-devel
时创建的
我找到了答案。感谢 YSC 为我指明了正确的道路。我只需要做一些额外的事情 Where Does GCC Look to Find its Header Files?
基本上,我需要将包含目录添加到 gcc 的 header 包含路径。我通过输入 cpp -I <desired path> -v
来做到这一点,对我来说是 /usr/src/kernels/......等
运行 刚刚 cpp -v
给了我一个包含路径 gcc 搜索的列表。只要确保它在那里。
所以现在我的 driver 模块可以正确构建并使用 include 语句作为 #include <linux/init.h>
加载,就像我想要的那样。