簡體   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