Cross compile modules linux

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

Достаточно давно хотел освоить сабж, но всё были другие более приоритетные дела. И вот настала очередь кросскомпиляции.

В данном посте будут описаны:

  1. Инструменты
  2. Элементарная технология кросскомпиляции
  3. И, собственно, HOW2

Кому это интересно, прошу под кат.

Вводная

Одно из развивающихся направлений в современном IT это IoT. Развивается это направление достаточно быстро, всё время выходят всякие крутые штуки (типа кроссовок со встроенным трекером или кроссовки, которые могут указывать направление, куда идти (специально для слепых людей)). Основная масса этих устройств представляют собой что-то типа «блютуз лампочки», но оставшаяся часть являет собой сложные процессорные системы, которые собирают данные и управляют этим огромным разнообразием всяких умных штучек. Эти сложные системы, как правило, представляют собой одноплатные компьютеры, такие как Raspberry Pi, Odroid, Orange Pi и т.п. На них запускается Linux и пишется прикладной софт. В основном, используют скриптовые языки и Java. Но бывают приложения, когда необходима высокая производительность, и здесь, естественно, требуются C и C++. К примеру, может потребоваться добавить что-то специфичное в ядро или, как можно быстрее, высчитать БПФ. Вот тут-то и нужна кросскомпиляция.

Если проект не очень большой, то его можно собирать и отлаживать прямо на целевой платформе. А если проект достаточно велик, то компиляция на целевой платформе будет затруднительна из-за временных издержек. К примеру, попробуйте собрать Boost на Raspberry Pi. Думаю, ожидание сборки будет продолжительным, а если ещё и ошибки какие всплывут, то это может занять ох как много времени.

Поэтому лучше собирать на хосте. В моём случае, это i5 с 4ГБ ОЗУ, Fedora 24.

Инструменты

Для кросскомпиляции под ARM требуются toolchain и эмулятор платформы либо реальная целевая платформа.

Т.к. меня интересует компиляция для ARM, то использоваться будет и соответствующий toolchain.

Toolchain’ы делятся на несколько типов или триплетов. Триплет обычно состоит из трёх частей: целевой процессор, vendor и OS, vendor зачастую опускается.

  • *-none-eabi — это toolchain для компиляции проекта работающего в bare metal.
  • *eabi — это toolchain для компиляции проекта работающего в какой-либо ОС. В моём случае, это Linux.
  • *eabihf — это почти то же самое, что и eabi, с разницей в реализации ABI вызова функций с плавающей точкой. hf — расшифровывается как hard float.

Описанное выше справедливо для gcc и сделанных на его базе toolchain’ах.

Сперва я пытался использовать toolchain’ы, которые лежат в репах Fedora 24. Но был неприятно удивлён этим:

Поискав, наткнулся на toolchain от компании Linaro. И он меня вполне устроил.

Второй инструмент- это QEMU. Я буду использовать его, т.к. мой Odroid-C1+ пал смертью храбрых (нагнулся контроллер SD карты). Но я таки успел с ним чуток поработать, что не может не радовать.

Элементарная технология кросскомпиляции

Собственно, ничего необычного в этом нет. Просто используется toolchain в роли компилятора. А стандартные библиотеки поставляются вместе с toolchain’ом.

Выглядит это так:

Какие ключи у toolchain’а можно посмотреть на сайте gnu, в соответствующем разделе.

Читайте также:  Программирование python под windows

Для начала нужно запустить эмуляцию с интересующей платформой. Я решил съэмулировать Cortex-A9.

После нескольких неудачных попыток наткнулся на этот how2, который оказался вполне вменяемым, на мой взгляд.

Ну сперва, само собою, нужно заиметь QEMU. Установил я его из стандартных репов Fedor’ы.

Далее создаём образ жёсткого диска, на который будет установлен Debian.

По этой ссылке скачал vmlinuz и initrd и запустил их в эмуляции.

Далее просто устанавливаем Debian на наш образ жёсткого диска (у меня ушло

После установки нужно вынуть из образа жёсткого диска vmlinuz и initrd. Делал я это по описанию отсюда.

Сперва узнаём смещение, где расположен раздел с нужными нам файлами:

Теперь по этому смещению примонтируем нужный нам раздел.

Копируем файлы vmlinuz и initrd и размонтируем жёсткий диск.

Теперь можно запустить эмуляцию.

И вот заветное приглашение:

Теперь с хоста по SSH можно подцепиться к симуляции.

Теперь можно и собрать программку. По Makefile’у ясно, что будет калькулятор. Простенький.

Собираем на хосте исполняемый файл.

Отмечу, что проще собрать с ключом -static, если нет особого желания предаваться плотским утехам с библиотеками на целевой платформе.

Копируем исполняемый файл на таргет и проверяем.

Собственно, вот такая она, эта кросскомпиляция.

UPD: Подправил информацию по toolchain’ам по комментарию grossws.

Источник

Cross-compile Linux kernel with additional modules

I am new to cross-compilation. I have to cross-compile a Linux kernel because I intend to use a wifi module with my TS-7500 SBC (ARM processor) and it does not support it. I have the drivers for my wifi module and through internet surfing I have come to know a general procedure of cross-compilation. However I am somewhat confused on the extra module portion. Here is the information from official website of TS-7500 regarding these extra modules:

Appendix — Compiling TS-Kernel with Custom Options In order to compile a separate kernel module and come out with a .ko file for inclusion in the already existing kernel, these are the steps to take following step 08 and ending at step 09 above. Note: Steps after step 02 are unverified/untested. They represent an accurate procedure which one would go through.

01.) Open menuconfig and modularize the kernel feature using «M». For example, to modularize cifs.ko, one would use the arrow and Enter keys to navigate to Filesystems -> Network File Systems -> CIFS Support.
Press «M» to modularize CIFS support into the kernel then keep hitting «exit» until you’re prompted to save changes, choose «yes».

02.) Compile the kernel with the modules and copy the modules to the Linux PC

03.) Retrieve the module which was copied to the Linux PC with a command like cp so that it can be installed into the kernel on the MiniSD card.

04.) Install the module into the kernel by copy and pasting from partition 4 of the card to partition 2 on the SBC.

05.) Finally, in order to use the new module, you must enable it. This can be included in a startup script such as linuxrc.

I am confused about serial 2. Can anyone explain this to me and where am I supposed to provide address of the drivers I want to install?

Источник

Cross compiling Linux ARM kernel modules

This guide will allow you to cross-compile a loadable kernel module (LKM; a.k.a. device driver) for a ARM Linux system.

Читайте также:  Установка яндекс карты для windows ce

1. Target system

I will use this configuration as an example, but you can apply the same method for other environments.

  • ARMv7 (32-bit)
  • ARM qemu emulating vexpress-a9 board
  • Linux is running in qemu.

2. Download linux kernel source

You must download the exact version which is running in the qemu.

Note that source for 3.2.0 is named linux-3.2.tar.gz , not linux-3.2.0.tar.gz .

3. Download cross compiler toolchain

Linaro’s prebuilt toolchain generally works well. Download one from https://releases.linaro.org/components/toolchain/binaries.

Pick a version, and choose the appropriate architecture. In our case, it would be arm-linux-gnueabihf (ARM 32-bit, linux, little endian, hard float).

There are three kinds of files: gcc-linaro- , runtime-gcc-linaro- , and sysroot-eglibc-linaro- . You only need the first one. For more info, refer to this Linaro wiki page.

For instance, go to 4.9-2017.01/arm-linux-gnueabihf/ directory and download gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz .

4. Take out kernel build config

We need to build the kernel first, and then build a kernel module. But to compile a kernel, we must have the exact build configuration of the currently running Linux system. Fortunately, you can get a copy from a running system. Look at these locations:

Copy the file out of the qemu using scp or something.

5. Build the kernel

You need auto-generated files in order to build a kernel module. Otherwise you may encounter an error message like this:

To build a kernel with given config file,

Complete kernel build may not be necessary because what you need is generated header files.

Источник

Embedded Handbook/General/Cross-compiling the kernel

General topics
Introduction
Creating a cross-compiler
Cross-compiling with Portage
Cross-compiling the kernel
Compiling with qemu user chroot
Frequently asked questions
Emulators
Qemu
Armulator
Hercules
Bootloaders
Das U-Boot
NeTTrom
RedBoot
SH-LILO
Boards
Hammer Board and Nail Board
LANTank
NetWinder
NSLU2
QNAP TurboStation 109/209/409
Marvell Sheevaplug
ACME SYSTEMS Netus G20
Genesi Efika MX
Pandaboard
TrimSlice
BeagleBone
BeagleBone Black
Intel Edison

Cross-compile a kernel for a system with flair!

Sources

First install the relevant kernel sources. A kernel sources package can be quickly emerged from the Gentoo ebuild repository or fetch the latest sources from kernel.org. The method for actually compiling the kernel is all the same.

You should install the kernel into the sysroot so that if you want to cross-compile packages which include kernel modules, the process will be transparent. Otherwise, the actual place where you build the kernel does not matter. Some people build all their kernels in /usr/src/ for example.

Setup cross-compiling

There are two fundamental variables that the kernel uses to select the target architecture. Normally these values are guessed based on your build environment, but of course that environment here does not match our target embedded system, so we’ll need to override them. The variables in question are ARCH and CROSS_COMPILE . The default values for both are found in the top-level Makefile and the values of both may be overridden on the command line.

The ARCH variable is the architecture you’re targeting as the kernel knows it. So while portage and other people may use «x86», the kernel uses «i386». Peek in the arch/ subdirectory real quick to figure out what you want to use.

Читайте также:  Vmware mac os перезагрузка

Hopefully the CROSS_COMPILE variable is pretty self-explanatory. Set this to the prefix of your toolchain (including the trailing dash «-«). So if your toolchain is invoked as say x86_64-pc-linux-gnu-gcc , just chop off that trailing gcc and that’s what you use: x86_64-pc-linux-gnu- .

There is an additional variable, INSTALL_MOD_PATH , which defines where the /lib directory will be created, and all the modules stored. While you don’t have to transfer the kernel sources to your target device, if you build any modules, you’ll want this directory.

There are really two ways you can setup the system. You can modify the toplevel Makefile or you can override the relevant variables on the command line. How you do it is largely a matter of taste, so we’ll cover both. Pick one of the following.

Overriding on the command-line (instead of in the Makefile ) would look something like this:

You can use a little helper script if you need to hop between different kernel trees at the same time. We’ll call this script xkmake :

So now when you want to build a kernel or do anything else, you just execute xkmake in place of make .

Configure and compile

At this point, configuring and compiling the kernel is like any other kernel, so we won’t go into depth as there are plenty of HOWTOs and guides out there which can treat the subject in much greater detail.

Источник

Кросскомпиляция модуля 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:

Содержимое Makefile, которым пытался собирать модуль:

/projects/linux-3.4.113/include по крайней мере пути к хеадерам ядра идут начиная с этой точки.

/projects/linux-3.4.113/ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-gcc . Да, кроме самих исходников нужен будет конфиг ядра и подготовить дерево исходников для сборки модулей примерно так: make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-gcc modules_prepare

1 ответ 1

Основные зависимости

Для сборки внешних модулей ядра обязательно надо иметь:

  • Исходные кода ядра, крайне желательно точно той же версии, что и на запущенном ядре (достаточно будет заголовочные файлы ядра с Makefile ‘ами [содержимое пакета linux-headers* в большинстве пакетных дистрибутивов])
  • Конфиг ядра под которое собираешь или максимально близкий.
  • [Кросс-]компилятор, make и прочую dev-мишуру

Типовая структура

hello.c:

Kbuild или Makefile, первое предпочтительнее. В простейшем случаее содержит одну строчку:

Подготовка дерева исходников ядра

Далее подразумевается, что исходники ядра распакованы в /tmp/linux , префикс кросс компилятора armv6j-hardfloat-linux-gnueabi , а целевая архитектура arm .

Желательно сделать oldconfig и ответить на сотню другую вопросов, но вполне хватит и silentoldconfig. Внимание на — в конце CROSS_COMPILE — это не ошибка, так и должно быть.

Стоит проверить, что поддержка модулей в ядре включена:

Подготовка дерева для сборки модулей:

Перед кросс компиляцией настоятельно советую потренироваться и собрать helloworld для текущего нативного ядра, всё точно также, но не надо указывать CROSS_COMPILE и ARCH .

Источник

Оцените статью