#linux #makefile #module #kernel
#c #linux #makefile создать файл #linux-ядро
Вопрос:
Можно ли создать модуль ядра из нескольких исходных файлов, один из которых имеет то же имя, что и модуль?
Например: я хочу создать «mymodule.ko» со следующими исходными файлами:
mymodule.c
mymodule_func.c
Этот makefile не работает:
#Makefile
obj-m = mymodule.o
mymodule-objs := mymodule.o mymodule_func.o
Спасибо
Ответ №1:
Я нашел решение, я поместил свой исходный файл в подпапку:
Создайте файл src/mymodule.c
src/mymodule_func.c
#Makefile
obj-m = mymodule.o
mymodule-objs := ./src/mymodule.o ./src/mymodule_func.o
all:
make -C $(KERNEL_PATH) M=$(PWD) modules
clean:
make -C $(KERNEL_PATH) M=$(PWD) clean
Комментарии:
1. Убедитесь, что ваши межфайловые функции не помечены как статические.
2. Не проще ли было бы переименовать mymodule.{c,o} в mymodule_main.{c, o} и не беспокоиться о дополнительном подкаталоге?
Ответ №2:
Правильный способ исправить в файле make ядра будет следующим:
#
obj-m = my_module.o
#append other source files except my_module.c which would be include by default
my_module-objs = src1.o src2.o
Комментарии:
1. Спасибо за этот ответ. Я нашел его наиболее полезным здесь.
2. Этот подход не сработал для меня, возможно, это зависит от версии ядра / kbuild. Я не исследовал его дальше…
Ответ №3:
Насколько я понимаю, невозможно, чтобы имя модуля и имя источника были одинаковыми. Было бы лучше указать имя модуля как module.o
и использовать Makefile для компиляции загружаемого модуля ядра, как показано ниже,
Makefile
# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
**obj-m := module.o
module-objs := mymodule.o mymodule_func.o**
# Otherwise we were called directly from the command
# line; invoke the kernel build system.
EXTRA_CFLAGS = -DDEBUG
else
KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
clean:
$(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) clean
Комментарии:
1. Полезным способом определения
KERNELDIR
является использование?=
вместо:=
so, чтобы по умолчанию он строился для текущего запущенного ядра, но может быть переопределен в командной строке make .
Ответ №4:
Вы можете использовать TARGET
для именования вашего файла .ko, как я сделал в этом примере:
TARGET = can
KDIR = /lib/modules/3.1.10-1.16-desktop/build
PWD := $(shell pwd)
obj-m = $(TARGET).o
can-objs := can_core.o can_open.o can_select.o can_sysctl.o can_write.o
can_close.o can_ioctl.o can_read.o can_util.o
can_debug.o can_error.o
can_async.o can_sim.o
default:
make -C $(KDIR) M=$(PWD) modules
Итак, после сборки я закончил с кучей объектных файлов и can.ko
Комментарии:
1. Если я добавлю объект can.o в can-objs, я получу удаление зависимости make[2]: Circular can.o <- can.o . Файл can.o не будет ссылкой
Ответ №5:
Другим решением является создание символической ссылки на файл, скажем:
mymodule.c: ln -sf mymodule.c _mymodule.c
Теперь используйте _mymodule.o
в качестве имени объекта:
mymodule-objs := _mymodule.o
Ответ №6:
Если кто-нибудь сталкивался с этой проблемой при работе с Xilinx SoC и petalinux, обратите внимание на сгенерированный файл .bb (bitbake). Помимо указания объектных файлов в файле Makefile:
modulename-objs = src1.o src2.o
все файлы (включая заголовки) должны быть перечислены в modulename.bb SRC_URI
переменная файла.