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

Вопросы программного кода и архитектуры Linux

Модератор: Olej

hiber
Интересующийся
Сообщения: 2
Зарегистрирован: 17 апр 2012, 17:16
Контактная информация:

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

Непрочитанное сообщение hiber » 17 апр 2012, 18:06

Всем привет.

Есть xUbuntu 11.10 на лаптопе и xUbuntu 11.10 под vBox на этой же машинке.
Есть простой пример, который билдится и подключается на обоих системах,
но на лаптопе сбилженный модуль не подключается на xUbunt'e под vBox:
insmod: error inserting 'test.ko': -1 Invalid module format
Кросс компилировал по этой доке http://www.linuxcenter.ru/lib/books/lkm ... ILEDKERNEL
Системы ставил из одного .iso, разница, максимум, в последующих обновлениях системм.

Подскажите, чего не хватает.
Спасибо.
test.zip
(4.35 КБ) 587 скачиваний
Acer Extensa 5620 Core2Duo
xUbuntu 11.10

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: кросс компиляция модуля ядра

Непрочитанное сообщение Olej » 18 апр 2012, 11:31

hiber писал(а):Всем привет.

Есть xUbuntu 11.10 на лаптопе и xUbuntu 11.10 под vBox на этой же машинке.
Есть простой пример, который билдится и подключается на обоих системах,
но на лаптопе сбилженный модуль не подключается на xUbunt'e под vBox:
insmod: error inserting 'test.ko': -1 Invalid module format
Кросс компилировал по этой доке http://www.linuxcenter.ru/lib/books/lkm ... ILEDKERNEL
Системы ставил из одного .iso, разница, максимум, в последующих обновлениях системм.

Подскажите, чего не хватает.
Ответ навскидку (позже подробнее посмотрю):

1. несоответствие версии (сигнатуры) ядра;

2. а что вам мешает собрать в той системе, где будете эксплуатировать?

3. посмотрите пока ;-) : http://rus-linux.net/MyLDP/BOOKS/Moduli ... index.html

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: кросс компиляция модуля ядра

Непрочитанное сообщение Olej » 18 апр 2012, 11:36

Olej писал(а): Кросс компилировал по этой доке http://www.linuxcenter.ru/lib/books/lkm ... ILEDKERNEL
Это источник очень старый!
Он писался для ядра ещё 2.4 ... почти 10 лет назад - и был первым и лучшим источником информации по модулям ядра.
Позже (лет 5-7 назад?) его подправили под 2.6... без участия первоначального автора, понаоставляв там непроверенных ошибок и "хвостов" из 2.4.

Пользоваться ним нужно с большой осторожностью!

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: кросс компиляция модуля ядра

Непрочитанное сообщение Olej » 18 апр 2012, 11:42

hiber писал(а): Подскажите, чего не хватает.
Спасибо.
test.zip
Диагноз ;-) :
- так у вас модуль (Makefile) для нативной сборки, там нет никакой кросс-компиляции!
- конечно он не станет на ядро с другой сигнатурой.

P.S. Пожелания:
- заворачивайте, пожалуйста, обсуждаемые архивы не в .zip, а в .tgz, или .tar.gz ... как это обычно принято в Linux.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: кросс компиляция модуля ядра

Непрочитанное сообщение Olej » 18 апр 2012, 13:00

hiber писал(а): Системы ставил из одного .iso, разница, максимум, в последующих обновлениях системм.
Обновлений достаточно (иногда), чтобы изменилась сигнатура ядра.
А этого достаточно, чтоб модуль распознавался как собранный под другое ядро.

P.S. это плата за хвалёную монолитность ядра. :lol:
А иначе (при более облегчённых условиях контроля соответствия) было бы просто невозможно удержать это монолитное ядро от самораспада :-?

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: кросс компиляция модуля ядра

Непрочитанное сообщение Olej » 18 апр 2012, 13:15

Olej писал(а): Диагноз ;-) :
- так у вас модуль (Makefile) для нативной сборки, там нет никакой кросс-компиляции!
- конечно он не станет на ядро с другой сигнатурой.
Я никогда не задавался вопросами:
- кросс-сборки модуля под другое ядро вручную...
- попыток загрузки модуля в обход контроля сигнатур
(вот то, что в названной ссылке The Linux Kernel Module Programming Guide описывается как опция --force-vermagic, что, как я сильно подозреваю, вообще не работает ... или всё не так просто и работает, но не так)

Я почему специально выделил "вручную"?
Да потому просто, что для кросс-сборки есть комплексные специальные проекты, один из лучших из которых - BuildRoot, и описано это было здесь в теме: Linux для embedded применений.
Так что в более сложных случаях (под другую таргет-архитектуру процессора, например) это лучше делать не руками, а использованием вот тех специализированных тулзов.

Но тема поднятая - интересная...
Стоит того, чтобы к ней вернуться, и, если автор вопроса не охладеет к нему - я готов детально покопаться и пообсуждать здесь.

Вопрос состоит в том, чтоб:
- кросс-скомпилировать простейший модуль для загрузки под другое ядро, но той же полностью архитектуры процессора + сделать это вручную.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: кросс компиляция модуля ядра

Непрочитанное сообщение Olej » 18 апр 2012, 13:32

Olej писал(а):
Olej писал(а): Диагноз ;-) :
- так у вас модуль (Makefile) для нативной сборки, там нет никакой кросс-компиляции!
- конечно он не станет на ядро с другой сигнатурой.
Я никогда не задавался вопросами:
- кросс-сборки модуля под другое ядро вручную...
- попыток загрузки модуля в обход контроля сигнатур
(вот то, что в названной ссылке

описывается как опция --force-vermagic, что, как я сильно подозреваю, вообще не работает ... или всё не так просто и работает, но не так)


Вопрос состоит в том, чтоб:
- кросс-скомпилировать простейший модуль для загрузки под другое ядро, но той же полностью архитектуры процессора + сделать это вручную.
Крос-компиляция, вообще то, дело непростое...
Всё, что пишут авторы The Linux Kernel Module Programming Guide на этот счёт, что нужно просто в Makefile определить:
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 5
EXTRAVERSION = -1.358custom
...
- это, по моему мнению, откровенная херня, и они сами это не делали и не проверяли.

Почему я так думаю?
Да потому, что все символы (имена) в модуле связываются тупо по абсолютным адресам размещения в ядре, и стоит ядро чуть-чуть поменять (попатчить, строчку добавить) и все абсолютные адреса поплывут, и такой модуль мгновенно завалит систему!

Собрать модуль под другое ядро я могу так, поменяв в Makefile всего одну строчку:

Код: Выделить всё

#CURRENT = $(shell uname -r)
CURRENT = 2.6.35.14-106.fc14.i686.PAE
- это при том, что сигнатура моего текущего ядра - 2.6.42.12-1.fc15.i686.PAE (отличается).

И сборка моего элементарного ядра:

Код: Выделить всё

[olej@notebook cross]$ make
make -C /lib/modules/2.6.35.14-106.fc14.i686.PAE/build M=/home/olej/2012_WORK/OWN.BOOKS/examples.DRAFT/cross modules
make[1]: Вход в каталог `/usr/src/kernels/2.6.35.14-106.fc14.i686.PAE'
  CC [M]  /home/olej/2012_WORK/OWN.BOOKS/examples.DRAFT/cross/cross.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/olej/2012_WORK/OWN.BOOKS/examples.DRAFT/cross/cross.mod.o
  LD [M]  /home/olej/2012_WORK/OWN.BOOKS/examples.DRAFT/cross/cross.ko
make[1]: Выход из каталога `/usr/src/kernels/2.6.35.14-106.fc14.i686.PAE'
[olej@notebook cross]$ modinfo cross.ko
filename:       cross.ko
author:         Oleg Tsiliuric <olej@front.ru>
license:        GPL
srcversion:     1C7ED44CA3899A79D36310E
depends:        
vermagic:       2.6.35.14-106.fc14.i686.PAE SMP mod_unload 686 
- модуль собрался ... и я так сильно предполагаю, что он будет загружаемый и всё ОК...

Но здесь есть хитрость ... я вас слегка обманул ;-) :
- у меня установлены все хэдер файлы (build-каталог) для этого ядра

Код: Выделить всё

[olej@notebook ~]$ ls -l /lib/modules
итого 12
drwxr-xr-x 6 root root 4096 марта 25 00:37 2.6.35.14-106.fc14.i686.PAE
drwxr-xr-x 6 root root 4096 марта 31 02:13 2.6.42.12-1.fc15.i686.PAE
drwxr-xr-x 3 root root 4096 марта 14 23:05 3.0.9
- и ни для какого иного ядра, кроме тех, что установлены в процессе обновлений, собрать модуль не получится.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: кросс компиляция модуля ядра

Непрочитанное сообщение Olej » 18 апр 2012, 20:31

Olej писал(а): Но здесь есть хитрость ... я вас слегка обманул ;-) :
- у меня установлены все хэдер файлы (build-каталог) для этого ядра

Код: Выделить всё

[olej@notebook ~]$ ls -l /lib/modules
итого 12
drwxr-xr-x 6 root root 4096 марта 25 00:37 2.6.35.14-106.fc14.i686.PAE
drwxr-xr-x 6 root root 4096 марта 31 02:13 2.6.42.12-1.fc15.i686.PAE
drwxr-xr-x 3 root root 4096 марта 14 23:05 3.0.9
- и ни для какого иного ядра, кроме тех, что установлены в процессе обновлений, собрать модуль не получится.
Но самые главные здесь даже не хэдер-файлы, хотя вы и можете нарваться на отсутствующий вызов API, или API с изменёнными прототипами (очень характерно между версиями 2.6.18 и 2.6.19) ... но не это здесь самое неприятное: нарвавшись на изменившийся вызов API ядра вы получите синтаксическое сообщение о несоответствии прототипа вызова + отсутствие результата компиляции... Такие ситуации только подсказывают разобраться "что происходит?" и устранить.

Куда важнее файл /lib/modules/`uname -r`/System.map - здесь абсолютные адреса имён (точек входа) API ядра.
См. ядро

Код: Выделить всё

[olej@notebook build]$ pwd
/lib/modules/2.6.42.12-1.fc15.i686.PAE/build
[olej@notebook build]$ cat System.map  | grep ' T ' | tail -n5
c0c8c259 T crypto_fpu_exit
c0c8c4a3 T crypto_exit_proc
c0c8ce66 T libata_transport_exit
c0c8d101 T xhci_unregister_pci
c0c8d232 T rtc_dev_exit
И то же имя в динамике, как оно загружено в текущем (этом же 2.6.42.12) ядре:

Код: Выделить всё

[olej@notebook build]$ cat /proc/kallsyms | grep rtc_dev_exit
c0c8d232 T rtc_dev_exit
Всё ОК, да?
Теперь начинаем компилировать модуль для другой версии ядра:

Код: Выделить всё

[olej@notebook build]$ pwd
/lib/modules/2.6.35.14-106.fc14.i686.PAE/build
[olej@notebook build]$ cat System.map  | grep rtc_dev_exit
c0ac095d T rtc_dev_exit
Что произошло?
Да то, что компилируя для версии ядра 2.6.35, если мы используем для этого текущий каталог построения ядра /lib/modules/2.6.42.12-1.fc15.i686.PAE/build, мы для вызова rtc_dev_exit() (я не знаю что это такое) подставим адрес c0c8d232, но в ядре 2.6.35 это должен быть c0ac095d, и при загрузке такого модуля ядро 2.6.35 разлетится вдребезги.

Ali
Писатель
Сообщения: 57
Зарегистрирован: 08 окт 2011, 08:00
Контактная информация:

Re: кросс компиляция модуля ядра

Непрочитанное сообщение Ali » 19 апр 2012, 06:30

В общем случае надо строить ядро, но в федоре и ряде других дистрибутивов придуман пакет kernel-devel.

Код: Выделить всё

[ali@f16 ~]$ rpm -ql kernel-devel-* | grep System
/usr/src/kernels/3.3.0-8.fc16.x86_64/System.map
/usr/src/kernels/3.3.1-3.fc16.x86_64/System.map
/usr/src/kernels/3.3.1-5.fc16.x86_64/System.map
[ali@f16 ~]$ rpm -qi kernel-devel-3.3.0-8.fc16.x86_64
Name        : kernel-devel
Version     : 3.3.0
Release     : 8.fc16
Architecture: x86_64
Install Date: Вс. 01 апр. 2012 19:04:37
Group       : System Environment/Kernel
Size        : 28999585
License     : GPLv2
Signature   : RSA/SHA256, Пт. 30 марта 2012 23:49:17, Key ID 067f00b6a82ba4b7
Source RPM  : kernel-3.3.0-8.fc16.src.rpm
Build Date  : Чт. 29 марта 2012 23:18:07
Build Host  : x86-05.phx2.fedoraproject.org
Relocations : (not relocatable)
Packager    : Fedora Project
Vendor      : Fedora Project
URL         : http://www.kernel.org/
Summary     : Development package for building kernel modules to match the kernel
Description :
This package provides kernel headers and makefiles [b]sufficient [/b]to build modules
against the kernel package.
[ali@f16 ~]$ 
Building Only Kernel Modules (Out Of Tree Modules)
Warning (medium size).png
This section needs to be updated and fleshed out

This section is for users who are only interested in working on a kernel module, and who do not wish to build an entire custom kernel. It is not necessary to download and rebuild the entire kernel in order to build a module. To build a module for the currently running kernel, only the matching kernel-devel package is required. Run the following command to install the kernel-devel package using yum.

su -c 'yum install kernel-devel'

Note.png
You may need to install 'kernel-PAE-devel' if you are using the PAE kernel

You can build against any kernel version, as long as you have kernel and kernel-devel packages installed for that version. The rest of this section assumes we're building for the running kernel; if not, replace `uname -r` with the desired version number.
Note.png
The kernel-doc package contains official Kbuild documentation - see files under Documentation/kbuild, in particular the modules.txt file.

As a simple example, to build the foo.ko module from foo.c, create the following Makefile in the directory containing the foo.c file:

obj-m := foo.o

KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

default:
[TAB]$(MAKE) -C $(KDIR) M=$(PWD) modules

[TAB] Denotes a tab character which must come first for makefile lines containing commands.

Then, issue the make command to build the foo.ko module.

The above is a helpful local Makefile wrapper invoking kbuild; in general you can simply do things like

# make -C /lib/modules/`uname -r`/build M=`pwd` modules
# make -C /lib/modules/`uname -r`/build M=`pwd` clean
# make -C /lib/modules/`uname -r`/build M=`pwd` modules_install

etc to build those targets.
http://fedoraproject.org/wiki/Building_ ... Modules.29

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: кросс компиляция модуля ядра

Непрочитанное сообщение Olej » 19 апр 2012, 11:18

Ali писал(а):В общем случае надо строить ядро, но в федоре и ряде других дистрибутивов придуман пакет kernel-devel.

Код: Выделить всё

[ali@f16 ~]$ rpm -ql kernel-devel-* | grep System
/usr/src/kernels/3.3.0-8.fc16.x86_64/System.map
/usr/src/kernels/3.3.1-3.fc16.x86_64/System.map
/usr/src/kernels/3.3.1-5.fc16.x86_64/System.map
[ali@f16 ~]$ rpm -qi kernel-devel-3.3.0-8.fc16.x86_64
Name        : kernel-devel
Version     : 3.3.0
Release     : 8.fc16
Architecture: x86_64
Install Date: Вс. 01 апр. 2012 19:04:37
Group       : System Environment/Kernel
Size        : 28999585
License     : GPLv2
Signature   : RSA/SHA256, Пт. 30 марта 2012 23:49:17, Key ID 067f00b6a82ba4b7
Source RPM  : kernel-3.3.0-8.fc16.src.rpm
Build Date  : Чт. 29 марта 2012 23:18:07
Build Host  : x86-05.phx2.fedoraproject.org
Relocations : (not relocatable)
Packager    : Fedora Project
Vendor      : Fedora Project
URL         : http://www.kernel.org/
Summary     : Development package for building kernel modules to match the kernel
Description :
This package provides kernel headers and makefiles [b]sufficient [/b]to build modules
against the kernel package.
[ali@f16 ~]$ 
Хорошее дополнение.
Оно опережает ровно тот вопрос, который я собирался задать:
- а что это они там намутили в составе пакета kernel-devel-* ?

Ну и ещё есть некоторые вопросы:

- (не вспомню) но для сборки своего модуля к kernel-devel-* в придачу нужно же и kernel-headers-* устанавливать? туда же ссылаются все #include из кода модуля...

- про "ряде других дистрибутивов"(с) ...
Как и в каких дистрибутивах дела обстоят?
Насколько я помню, ещё в CenrOS 5.0, а это год ~2008, не нужны были исходники ядра (и собирать ядро) для сборки модулей.
В RedHat, наверное, то же самее...
А что там у Debian/Ubuntu ?

Ответить

Вернуться в «Linux изнутри»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 5 гостей