Страницы

Поиск по вопросам

понедельник, 18 февраля 2019 г.

Кросскомпиляция модуля helloworld

Добрый день. Пытаюсь собрать модуль helloworld под другую машину. Хост x86_64, таргет armhf Установил кросскомилятор /usr/bin/arm-linux-gnueabihf-gcc, скачал исходники ядра под данную машину ~/projects/linux-3.4.113/ Пытаюсь собрать (пробовал через makefile, переменные, но поскольку ничего не получилось, пытаюсь уже в лоб): /usr/bin/arm-linux-gnueabihf-gcc -I~/projects/linux-3.4.113/ -c ./helloworld.c
(и много всяких мелких вариаций похожей команды) На что раз за разом получаю ругань о том, что linux/modules.h не найден. Может кто объяснить что я делаю не так, и как надо правильно? Исходный код helloworld:
/* * hello-1.c - The simplest kernel module. */ #include /* Needed by all modules */ #include /* Needed for KERN_INFO */
int init_module(void) { printk(KERN_INFO "Hello world 1.
");
/* * A non 0 return means init_module failed; module can't be loaded. */ return 0; }
void cleanup_module(void) { printk(KERN_INFO "Goodbye world 1.
"); }
Содержимое Makefile, которым пытался собирать модуль:
CC := g++ TOOLCHAIN := arm-linux-gnueabihf PT := CFL := -Wextra -std=c++11 TPATH := /usr/bin/ LPATH := /usr/$(TOOLCHAIN)/ ARCH := arm all: helloworld.c $(TPATH)$(TOOLCHAIN)-$(CC) $(CFL) $(ARCH) -o helloworld.c


Ответ

Основные зависимости
Для сборки внешних модулей ядра обязательно надо иметь:
Исходные кода ядра, крайне желательно точно той же версии, что и на запущенном ядре (достаточно будет заголовочные файлы ядра с Makefile'ами [содержимое пакета linux-headers* в большинстве пакетных дистрибутивов]) Конфиг ядра под которое собираешь или максимально близкий. [Кросс-]компилятор, make и прочую dev-мишуру
Типовая структура
. ├── hello.c └── Kbuild
hello.c
#include #include
int init_module(void) { printk(KERN_INFO "Hello cruel world.
"); return 0; }
void cleanup_module(void) { printk(KERN_INFO "Goodbye cruel world.
"); }
Kbuild или Makefile, первое предпочтительнее. В простейшем случаее содержит одну строчку:
obj-m += hello.o
Подготовка дерева исходников ядра
Далее подразумевается, что исходники ядра распакованы в /tmp/linux, префикс кросс компилятора armv6j-hardfloat-linux-gnueabi, а целевая архитектура arm
Создайм config:
$ cd /tmp/linux $ cp /path/to/my/kernel/config ./.config
Желательно сделать oldconfig и ответить на сотню другую вопросов, но вполне хватит и silentoldconfig. Внимание на - в конце CROSS_COMPILE — это не ошибка, так и должно быть.
$ make ARCH=arm CROSS_COMPILE=armv6j-hardfloat-linux-gnueabi- silentoldconfig
Стоит проверить, что поддержка модулей в ядре включена:
$ grep CONFIG_MODULES .config CONFIG_MODULES_USE_ELF_REL=y CONFIG_MODULES=y CONFIG_MODULES_TREE_LOOKUP=y
Подготовка дерева для сборки модулей:
$ make ARCH=arm CROSS_COMPILE=armv6j-hardfloat-linux-gnueabi- modules_prepare
Перед кросс компиляцией настоятельно советую потренироваться и собрать helloworld для текущего нативного ядра, всё точно также, но не надо указывать CROSS_COMPILE и ARCH
Сборка модуля
$ cd /path/to/my/module $ make -C /tmp/linux ARCH=arm CROSS_COMPILE=armv6j-hardfloat-linux-gnueabi- M=$PWD modules
make: вход в каталог «/tmp/linux»
WARNING: Symbol version dump ./Module.symvers is missing; modules will have no dependencies and modversions.
CC [M] /tmp/hello-module/hello.o Building modules, stage 2. MODPOST 1 modules CC /tmp/hello-module/hello.mod.o LD [M] /tmp/hello-module/hello.ko make: выход из каталога «/tmp/linux»
$ file hello.ko hello.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]=16266c17567bf164e6fd4f48a52ecf477dad55cb, not stripped
Всё, как видно на выходе получен hello.ko
Предупреждение про Module.symvers можно игнорировать покуда нет зависимостей от других модулей. Иначе нужно будет пересобрать модули самого ядра или разжиться данным файлом.
К прочтению:
Documentation/kbuild/modules.txt

Комментариев нет:

Отправить комментарий