Создание модуля ядра из нескольких исходных файлов, один из которых имеет то же имя, что и модуль

#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 переменная файла.