You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Kbuild在树外Linux内核驱动中支持子目录编译?

问题:树外内核驱动与设备树Overlay一同编译适配DKMS

背景

现有可正常编译运行的树外Linux内核驱动仓库,子目录包含可单独编译的设备树overlay,需将.dtbo与驱动代码一同编译,适配DKMS管理。

当前配置

Kbuild文件

obj-m := mydriver.o
mydriver-objs += mydriver-dev.o mydriver-controls.o mydriver-registers.o
mydriver-objs += mydriver-status-sysfs.o mydriver-sysfs.o

subdir-y := device-trees

Makefile文件

ifneq ($(KERNELRELEASE),)
# legacy compatible kbuild part of makefile
  include Kbuild
else
# local normal makefile for external module

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
BUILDDIR ?= $(shell pwd)/build
SRCDIR ?= $(shell pwd)

all default: modules
install: modules_install

modules modules_install help clean:
    $(MAKE) -C $(KERNELDIR) M=$(BUILDDIR) src=$(SRCDIR) $@

endif

错误现象

移除subdir-y配置时编译正常,添加后出现递归错误:

make -C /lib/modules/6.6.31-current-bcm2712/build M=/home/builder/projects/platform_v4l2_driver/build src=/home/builder/projects/platform_v4l2_driver modules
make[1]: Entering directory '/usr/src/linux-headers-6.6.31-current-bcm2712'
scripts/Makefile.build:64: '/home/builder/projects/platform_v4l2_driver/build/device-trees/mydriver.ko' will not be built even though obj-m is specified.
scripts/Makefile.build:65: You cannot use subdir-y/m to visit a module Makefile. Use obj-y/m instead.
scripts/Makefile.build:64: '/home/builder/projects/platform_v4l2_driver/build/device-trees/device-trees/mydriver.ko' will not be built even though obj-m is specified.
scripts/Makefile.build:65: You cannot use subdir-y/m to visit a module Makefile. Use obj-y/m instead.
...

替换为obj-y := device-trees/后递归问题更严重。

解决方案

核心思路

Kbuild的subdir-y/obj-y不适合处理设备树Overlay编译(不属于内核模块或内置代码流程),需单独为device-trees目录编写编译规则,在主Makefile中触发,同时兼容DKMS流程。

修改后的配置

1. 主目录Kbuild(保留驱动配置)

obj-m := mydriver.o
mydriver-objs += mydriver-dev.o mydriver-controls.o mydriver-registers.o
mydriver-objs += mydriver-status-sysfs.o mydriver-sysfs.o

2. device-trees目录下创建Kbuild文件

假设目录内有mydriver-overlay.dts,配置如下:

dtbo-y += mydriver-overlay.dtbo

# 设备树编译通用规则
always := $(dtbo-y)
clean-files := $(dtbo-y)

3. 修改主目录Makefile

添加设备树编译与安装逻辑,兼容DKMS:

ifneq ($(KERNELRELEASE),)
  include Kbuild
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
BUILDDIR ?= $(shell pwd)/build
SRCDIR ?= $(shell pwd)
DT_DIR := $(SRCDIR)/device-trees
DT_BUILD_DIR := $(BUILDDIR)/device-trees

all default: modules dtbo
install: modules_install dtbo_install

# 编译驱动模块
modules modules_install help clean:
	$(MAKE) -C $(KERNELDIR) M=$(BUILDDIR) src=$(SRCDIR) $@

# 编译设备树Overlay
dtbo:
	mkdir -p $(DT_BUILD_DIR)
	$(MAKE) -C $(KERNELDIR) M=$(DT_BUILD_DIR) src=$(DT_DIR) dtbs

# 安装设备树Overlay(适配标准路径,可按需调整)
dtbo_install:
	mkdir -p /boot/overlays
	cp $(DT_BUILD_DIR)/*.dtbo /boot/overlays/

# 清理设备树编译产物
clean: clean_dtbo
clean_dtbo:
	rm -rf $(DT_BUILD_DIR)

endif

关键说明

  • 设备树编译通过单独调用内核Makefile的dtbs目标完成,避免与驱动模块Kbuild流程冲突
  • 分离驱动与设备树的编译目录,彻底解决递归问题
  • dtbo_install将产物放到标准/boot/overlays目录,适配多数嵌入式系统(如树莓派),可根据实际系统调整路径
  • DKMS会自动识别Makefile中的all、install、clean目标,无需额外配置即可同时管理驱动与设备树Overlay

内容的提问来源于stack exchange,提问作者Michał Fita

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 10:57:16