Сборка модуля ядра Linux из дерева в отдельном объектном каталоге - PullRequest
8 голосов
/ 19 апреля 2011

Я сопоставляю систему сборки ядра Linux (Kbuild, kernel ≥2.6.28) со структурой каталогов и системой сборки для более крупного проекта.Наш проект содержит модуль ядра 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.Все выходные файлы должны заканчиваться output/linux-arm-debug (или любой другой архитектурой и вариантом отладки, которые были выбраны во время сборки).

Я прочитал kbuild/modules.txt и начал писать свой Kbuild file:

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.c и foo_linux.o из …/checkout/src/linux-driver/foo_linux.c?

Ответы [ 6 ]

4 голосов
/ 16 июня 2016

Вот 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
3 голосов
/ 11 декабря 2013

У меня была похожая проблема.Я изменил 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)`
1 голос
/ 28 апреля 2011

Мое не элегантное, но эффективное решение - скопировать исходные файлы в дерево вывода.

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)
0 голосов
/ 11 декабря 2012

Вы можете установить переменную окружения KBUILD_OUTPUT. Эта функция аналогична опции O=; однако, поскольку это переменная окружения, она может охватывать несколько make-файлов, где O= не может быть передано или требуется построить модуль вне каталога. У меня возникла та же проблема с попыткой собрать набор беспроводных модулей, и мне нужно было использовать O= для фактической сборки образа ядра.

0 голосов
/ 31 мая 2012

Немного поздно, но похоже, что O = flag - это то, что вам нужно.

0 голосов
/ 28 апреля 2011

Несмотря на то, что вы еще не упомянули то, что вы пробовали (или уже нашли решение), похоже, вам просто нужно немного продвинуться дальше по файлу 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.
...