这是我第一次创建内核模块(设备驱动程序),我只是想在我的 Raspberry Pi 变砖之后在模拟器(QEMU)中测试我的模块:(
在开始之前,我的源代码是https://github.com/thinkty/n7d-lkm。 (我目前正在关注 LDD3 书,我听说这本书已经过时了,所以关于代码的任何建议也很棒!)
我克隆了 Buildroot git 存储库,它位于
~/repos/buildroot
中。我不想污染 Buildroot 源代码,所以我决定使用 br2-external 树。根据文档和其他几个 StackOverflow 帖子,我在项目目录中创建了以下 3 个文件 (~/projects/n7d-lkm
):
name: N7D
desc: Numerical 7 segment display device driver
################################################################################
#
# n7d
#
################################################################################
N7D_VERSION = 0.1
N7D_SITE = $(BR2_EXTERNAL_N7D_PATH)
N7D_SITE_METHOD = local
N7D_LICNSE = GPL-2.0
N7D_LICENSE_FILES = LICENSE
$(eval $(kernel-module))
$(eval $(generic-package))
config BR2_PACKAGE_N7D
bool "n7d"
depends on BR2_LINUX_KERNEL
help
Numerical 7-segment display device driver for linux
https://github.com/thinkty/n7d-lkm.git
comment "n7d needs toolchain w/ headers >= 5.15, and a Linux kernel to be built"
depends on !BR2_LINUX_KERNEL
我的配置错误吗? 这里也是我的
~/repos/buildroot/.config
文件。
另外,下面是我的 Makefile 和 Kbuild:
# See https://www.kernel.org/doc/Documentation/kbuild/modules.txt
KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
MODULE_DIR := $(shell pwd)
default:
$(MAKE) -C $(KERNEL_DIR) M=$(MODULE_DIR) modules
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(MODULE_DIR) clean
.PHONY: default clean
MODULE := n7d
OBJECTS := n7d_device.o n7d_main.o
obj-m += $(MODULE).o
$(MODULE)-y := $(OBJECTS)
ccflags-y += -Wall -Werror -Iinclude
附注这也是我第一次写 StackOverflow 问题,所以如果有什么遗漏或者我应该做的事情请告诉我。
我首先将 Buildroot 分支更改为
2023.08.x
(git checkout 2023.08.x)。
在我的第一个 Buildroot make 中,我执行了 make BR2_EXTERNAL=~/projects/n7d-lkm qemu_arm_versatile_defconfig
并执行了 make BR2_EXTERNAL=~/projects/n7d-lkm menuconfig
选择“外部选项”下的 n7d
选项。
然后,我签入了 Buildroot 目录中的 .config
文件并验证了“BR2_PACKAGE_N7D=y”是否存在。
我尝试运行一个干净的重建,但我仍然找不到(尝试了modprobe,检查了modules.dep)我在QEMU中的内核模块(使用脚本启动QEMU ~/repos/buildroot/output/images/start-qemu .sh).在 StackOverflow 上看到类似问题的帖子 Can't compile a module using buildroot 后,我尝试编译该模块。由于当我在项目目录上执行 make clean all
时它编译得很好,因此我尝试在 buildroot 目录中运行
make
、make n7d
和 make N7D
来尝试通过 Buildroot 构建模块本身到输出图像,但我得到了错误消息 make host-n7d
所以我认为我的模块根本没有被 Buildroot 识别。当我在更改项目中的某些内容后执行make: *** No rule to make target 'n7d'. Stop.
时,我认为我没有得到与我的项目相关的任何内容。
Here是
make
命令的输出。
当我这样做 make
时,它就会返回make | grep n7d
我不知道为什么......
我尝试将项目目录中的 Makefile 更新为:
find: ‘/home/thinkty/repos/buildroot/output/target/usr/libexec/’: No such file or directory
mke2fs 1.47.0 (5-Feb-2023)
查看是否是 Kbuild 的问题,但结果还是一样。
总的来说,我的问题是“如何正确创建内核模块的外部树以使用 Buildroot 构建映像?”
此外,非常感谢对我的代码的任何建议!谢谢!
中所述,外部树的结构(简化)应该是:
# See https://www.kernel.org/doc/Documentation/kbuild/modules.txt
KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
MODULE_DIR := $(shell pwd)
MODULE := n7d
OBJECTS := $(addsuffix .o, $(notdir $(basename $(wildcard $(BR2_EXTERNAL_KERNEL_MODULE_PATH)/*.c))))
obj-m += $(MODULE).o
$(MODULE)-y := $(OBJECTS)
ccflags-y += -Wall -Werror -Iinclude
default:
$(MAKE) -C $(KERNEL_DIR) M=$(MODULE_DIR) modules
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(MODULE_DIR) clean
.PHONY: default clean
即,
+-- package/
| +-- package1/
| | +-- Config.in
| | +-- package1.mk
| +-- package2/
| +-- Config.in
| +-- package2.mk
|
+-- Config.in
+-- external.mk
+-- external.desc
应仅包含
external.mk
目录的包含内容。包 mk 文件必须始终位于与包同名的目录中。
所以,将内容放入
packages
并将以下内容放入
package/n7d/n7d.mk
:external.mk