Как собрать модуль (драйвер) ядра линукс, используя
configure, automake, autoconf и прочие «авто-утилиты».
Модули ядра линукс это файлы с расширением «.ko». Как правило для загрузки модуля используется команда «insmod», либо команда «modprobe». Для выгрузки модуля используется команда «rmmod». Для просмотра списка загруженных модулей существует команда «lsmod». Для получения информации о модуле используется команда «modinfo».
Пример сборки модуля с помощью autotools:
1. Создадим директорию для проекта module.
2. В директории module создадим директорию src.
3. В src создадим файл module_hello.c
/* src/module_hello.c */ #include <linux/init.h> #include <linux/module.h> static int __init hello_init(void) { printk("Hello, world!\n"); return 0; } module_init(hello_init); static void __exit hello_exit(void) { printk("Goodbye, world!\n"); } module_exit(hello_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("noname"); MODULE_DESCRIPTION("\"Hello, world!\" test module"); MODULE_VERSION("printk");
Алгоритм сборки модуля ядра с помощью autotools, немного отличается от алгоритма сборки простой программы или библиотеки. Потребуется создать еще два дополнительных Makefile.
В корневой директории модуля ( в директории module ) создаём файл:
# Makefile.am SUBDIRS = src
Ключевое слово SUBDIRS означает, что исходные файлы для сборки находятся в данной директории.
Также нужно создать Makefile.am в директории src следующего содержания:
# src/Makefile.am EXTRA_PROGRAMS = automake_dummy automake_dummy_SOURCES = module_hello.c module_DATA = module_hello.o include ../Makefile.common
automake_dummy_SOURCES — исходники из которых будет собираться модуль.
module_DATA = module_hello.o - название модуля.
include ../Makefile.common - обязательно нужно подключить внешний файл, который и будет выполнять сборку модуля. Он должен располагаться в корневом каталоге модуля.
Создаём файл Makefile.common в корневой директории модуля ( в директории module )
# Makefile.common moduledir = @moduledir@ KERNEL_LOCATION=@kerneldir@ KBUILD_VERBOSE = 1 MOD_DEVDIR = $(PWD) export module_DATA $(module_DATA): $(automake_dummy_SOURCES) mv Makefile Makefile.automake cp $(srcdir)/../Makefile.kernel Makefile CPPFLAGS="" CFLAGS="" LDFLAGS="" \ $(MAKE) -C $(KERNEL_LOCATION) \ ARCH="x86" CC="gcc" M=$(PWD) modules\ KBUILD_VERBOSE=$(KBUILD_VERBOSE) mv Makefile.automake Makefile CLEANFILES = $(module_DATA) .$(module_DATA).flags $(module_DATA:.o=.mod.c) $(module_DATA:.o=.@kernelext@) *~
Здесь происходит подмена Makefile на Makefile.kernel и запускается сборка модуля. Очень важным параметром сборки является инициализация переменной KERNEL_LOCATION. Она будет инициализирована в configure, через передачу параметров. Либо можно заменить строку:
$(MAKE) -C $(KERNEL_LOCATION) \
на
$(MAKE) -C /lib/modules/$(shell uname -r)/build \
Последний файл который нужно создать это файл Makefile.kernel. Он должен располагаться в корневой директории модуля ( в директории module ):
# Makefile.kernel obj-m=$(module_DATA) MI_OBJS = $(module_DATA) all clean: mv Makefile.automake Makefile $(MAKE) $@
Всё этого достаточно.
configure.in создадим с помощью утилиты autoscan. Эта программа создает файл configure.scan, который и является прототипом configure.in.
Выполняем:
autoscan
Правим configure.scan и затем переименовываем его в configure.in :
# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.65]) AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS]) AC_CONFIG_SRCDIR([src/module_hello.c]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE AC_PATH_KERNEL_SOURCE # Checks for programs. AC_PROG_CC # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT
Макрос AC_PATH_KERNEL_SOURCE добавляет к configure опцию --with-kerneldir, в которой нужно передавать путь ("/lib/modules/$(shell uname -r)/build"). Если этот параметр не передать в явном виде, то путь будет найден автоматически. И будет передан по умолчанию. Этот параметр необходим для выполнения кросс-компиляции.
ВСЁ! Теперь выполняем следующую последовательность действий и Makefile готов.
aclocal - создает aclocal.m4.
autoconf - утилита создает скрипт configure в соответствии с макросами указанными в файле `configure.in'.
autoheader — создает заголовочный файл (config.h.in).
touch NEWS README AUTHORS ChangeLog (эти файлы нужны для automake )
automake --add-missing - программа создает файлы"Makefile.in", на основе файлов "Makefile.am".
configure — создает Makefile
make — собирает модуль