繁体   English   中英

在单独的对象目录中构建树外 Linux 内核模块

[英]Building an out-of-tree Linux kernel module in a separate object directory

我正在面对 Linux 内核构建系统(Kbuild,内核 ≥2.6.28)以及更大项目的目录结构和构建系统。 我们的项目包含一个 out-of-tree Linux 内核模块,我们的目录结构如下所示(显然是简化的):

checkout/src/common/*.c           source files (common to Linux and other platforms)
checkout/src/linux-driver/*.c     source files (for the Linux kernel driver)
checkout/build/linux/Kbuild       Kbuild
tmp/linux-2.6.xx/                 where the Linux kernel is unpacked and configured
output/linux-arm-debug/           where object files must end up

构建过程不得修改checkout下的任何内容,构建模块不得修改tmp/linux-2.6.xx下的任何tmp/linux-2.6.xx 所有输出文件都必须在output/linux-arm-debug (或在构建时选择的任何架构和调试变体)。

我已经阅读了kbuild/modules.txt ,并开始编写我的Kbuild文件:

MOD_OUTPUT_DIR = ../../../output/linux-$(ARCH)-$(DEBUG)
obj-m += $(MOD_OUTPUT_DIR)/foo_mod.o
$(MOD_OUTPUT_DIR)/our_module-objs := $(MOD_OUTPUT_DIR)/foo_common.o $(MOD_OUTPUT_DIR)/foo_linux.o

这处理将目标文件存储在与Kbuild所在目录不同的目录中。 现在我如何指定foo_common.o需要从…/checkout/src/common/foo_common.cfoo_linux.o…/checkout/src/linux-driver/foo_linux.c

这是一个 Makefile,它为内核树模块之外的源树构建(改编自 @Mark 的评论)...

KDIR ?= /lib/modules/$(shell uname -r)/build
BUILD_DIR ?= $(PWD)/build
BUILD_DIR_MAKEFILE ?= $(PWD)/build/Makefile

default: $(BUILD_DIR_MAKEFILE)
    make -C $(KDIR) M=$(BUILD_DIR) src=$(PWD) modules

$(BUILD_DIR):
    mkdir -p "$@"

$(BUILD_DIR_MAKEFILE): $(BUILD_DIR)
    touch "$@"

clean:
    make -C $(KDIR) M=$(BUILD_DIR) src=$(PWD) clean

注意:您仍然需要一个 Kbuild 文件...

obj-m += my_driver.o

我有一个类似的问题。 我修改了linux_2_6_34/scripts/Makefile.build如下。

ifdef SRCDIR
src := $(SRCDIR)
else
src := $(obj)
endif

SRCDIR是目录源。

要编译模块,请运行

make -c $(KDIR) M=$(Your_output_dir) SRCDIR=$(your source directory)`

我不雅但有效的解决方案是将源文件复制到输出树中。

FOO_SOURCES_DIR = $(src)/../../../checkout/src
FOO_MOD_OUTPUT_DIR = ../../../output/linux-$(ARCH)-$(DEBUG)

# Specify the object files
obj-m += $(FOO_MOD_OUTPUT_DIR)/foo_mod.o
FOO_MODULE_OBJS := $(FOO_MOD_OUTPUT_DIR)/foo_common.o $(FOO_MOD_OUTPUT_DIR)/foo_linux.o
$(FOO_MOD_OUTPUT_DIR)/foo_mod-objs := $(FOO_MODULE_OBJS)

# Where to find the sources
$(src)/$(FOO_MOD_OUTPUT_DIR)/foo_common.c: $(FOO_SOURCES_DIR)/common/foo_common.c
$(src)/$(FOO_MOD_OUTPUT_DIR)/foo_linux.c: $(FOO_SOURCES_DIR)/linux-driver/foo_linux.c

# Rules to copy the sources
FOO_COPIED_SOURCES = $(patsubst %.o,$(src)/%.c,$(FOO_MODULE_OBJS))
$(FOO_COPIED_SOURCES):
        $(Q)mkdir -p $(@D)
        cp -f $< $@
clean-files += $(FOO_COPIED_SOURCES)
clean-dirs += $(FOO_MOD_OUTPUT_DIR)

虽然到目前为止您还没有提到您尝试过的内容(或者您是否已经找到了解决方案),但看起来您只需要进一步深入modules.txt文件 - 到第 4.3 节

--- 4.3 Several Subdirectories

kbuild can handle files that are spread over several directories.
Consider the following example:

.
|__ src
|   |__ complex_main.c
|   |__ hal
|   |__ hardwareif.c
|   |__ include
|       |__ hardwareif.h
|__ include
    |__ complex.h

To build the module complex.ko, we then need the following
kbuild file:

    --> filename: Kbuild
    obj-m := complex.o
    complex-y := src/complex_main.o
    complex-y += src/hal/hardwareif.o

    ccflags-y := -I$(src)/include
    ccflags-y += -I$(src)/src/hal/include

As you can see, kbuild knows how to handle object files located
in other directories. The trick is to specify the directory
relative to the kbuild file's location. That being said, this
is NOT recommended practice.

For the header files, kbuild must be explicitly told where to
look. When kbuild executes, the current directory is always the
root of the kernel tree (the argument to "-C") and therefore an
absolute path is needed. $(src) provides the absolute path by
pointing to the directory where the currently executing kbuild
file is located.

有点晚了,但看起来O= 标志是您所需要的。

您可以设置环境变量KBUILD_OUTPUT 此功能类似于O=选项; 但是,由于它是一个环境变量,因此它可以跨越多个 makefile,其中O=无法传递或需要构建目录外模块。 我在尝试构建一组兼容无线模块时遇到了同样的问题,我需要使用O=来构建实际的内核映像。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM