- Кросскомпиляция под ARM
- Вводная
- Инструменты
- Элементарная технология кросскомпиляции
- Русские Блоги
- [Linux] Кросс-компиляция драйвера как модуля
- Вопрос 1: Шаги для компиляции модуля
- Вопрос 2: Подготовка ядра
- Вопрос 3: самый основной компонент модуля
- Driver/module cross compilation
- 3 Answers 3
- Cross Compiling Linux Arm Kernel with new driver module
- Booting kernel from Legacy Image at 81800000 .
- 1 Answer 1
- Cross compiling Linux Kernel drivers
Кросскомпиляция под ARM
Достаточно давно хотел освоить сабж, но всё были другие более приоритетные дела. И вот настала очередь кросскомпиляции.
В данном посте будут описаны:
- Инструменты
- Элементарная технология кросскомпиляции
- И, собственно, 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, в соответствующем разделе.
Для начала нужно запустить эмуляцию с интересующей платформой. Я решил съэмулировать Cortex-A9.
После нескольких неудачных попыток наткнулся на этот how2, который оказался вполне вменяемым, на мой взгляд.
Ну сперва, само собою, нужно заиметь QEMU. Установил я его из стандартных репов Fedor’ы.
Далее создаём образ жёсткого диска, на который будет установлен Debian.
По этой ссылке скачал vmlinuz и initrd и запустил их в эмуляции.
Далее просто устанавливаем Debian на наш образ жёсткого диска (у меня ушло
После установки нужно вынуть из образа жёсткого диска vmlinuz и initrd. Делал я это по описанию отсюда.
Сперва узнаём смещение, где расположен раздел с нужными нам файлами:
Теперь по этому смещению примонтируем нужный нам раздел.
Копируем файлы vmlinuz и initrd и размонтируем жёсткий диск.
Теперь можно запустить эмуляцию.
И вот заветное приглашение:
Теперь с хоста по SSH можно подцепиться к симуляции.
Теперь можно и собрать программку. По Makefile’у ясно, что будет калькулятор. Простенький.
Собираем на хосте исполняемый файл.
Отмечу, что проще собрать с ключом -static, если нет особого желания предаваться плотским утехам с библиотеками на целевой платформе.
Копируем исполняемый файл на таргет и проверяем.
Собственно, вот такая она, эта кросскомпиляция.
UPD: Подправил информацию по toolchain’ам по комментарию grossws.
Источник
Русские Блоги
[Linux] Кросс-компиляция драйвера как модуля
Недавно я работал над драйверами для Linux, и было много проблем. Давайте сделаем запись.
Вопрос 1: Шаги для компиляции модуля
Чтобы скомпилировать модуль, вам необходимо подготовить следующие инструменты:
Полный и чистый исходный код ядра можно найти на официальном сайтеhttps://mirrors.edge.kernel.org/pub/linux/kernel/При загрузке вы должны обращать внимание на то же самое ядро, которое использовалось при редактировании ядра.Если оно неправильно скомпилировано, оно может не сообщать об ошибке, но при использовании insmod может возникнуть волшебная ошибка версии.
Цепочка инструментов кросс-компиляции готова,Различные цепочки инструментов кросс-компиляции, Общие
aarch64-linux-gnu-
arm-linux-gnueabi-
arm-none-eabi
Смотрите в другом блоге разницу[Embedded Linux] — кросс-компилятор вооружений gnueabi, none-eabi, arm-eabi, gnueabihf, разница gnueabi
Вы также можете столкнуться с ошибками, такими как openssl, вы можете установить соответствующую библиотеку на Baidu.
Вопрос 2: Подготовка ядра
Когда дело доходит до загрузки чистого исходного кода ядра, здесь возникает другой вопрос: нужно ли изменять исходный код ядра в соответствии с реальной ситуацией на плате? Ответ — нет, но вам нужно сделать menuconfig, чтобы сгенерировать файл .config и сделать компиляцию один раз, кроме того, Измените Makefile корневого каталога верхнего уровня, измените ARCH и CROSS_COMPILE
ARCH := arm64
CROSS_COMPILE := aarch64-linux-gnu-
Вопрос 3: самый основной компонент модуля
Ниже приведен простейший модуль модуля HelloWorld:
Источник
Driver/module cross compilation
I am trying to cross compile a driver for an arm based board. In the make file the search path for include files is that of the host machine’s kernel i.e it points to the linux headers that come with ubuntu. I also have the kernel source tree of target board present on the host system(i7/ubuntu). My Question is that which include path is needed for cross compilation (native system’s linux headers path or the path to the kernel source tree of board ? Does same thing applies to all modules including drivers?
3 Answers 3
Here is a Makefile for an out of tree driver. The architecture, toolchain and kernel dir specified :
When make is called from the module directory, the command line path is taken, and make is redirected to the kernel directory build system using make -C . The kernel build system then the different variable passed to it to go back into the module directory with everything setup (include path, toolchain etc ..) to compile a module. This second time through the Makefile, the kbuild path is taken, and the module is built as if it was in-tree.
Compiling with your build-system’s headers is spectacularly bad news, and may subtle binary incompatibilities that manifest themselves as seemingly bizarre crashes on the target.
As you’ve already discovered, the kernel is already hardened against this and will refuse to load modules built against the wrong headers. You’ll need to build using the same source tree as the existing kernel — including any patches. You might as well at this point rebuild the entire kernel.
The kernel tree is self-contained, so simply cross-compiling it in place will work. If you’re adding a driver it’s probably easiest to compile it in-tree.
If you want to build any user-space components, you have two solutions:
- Pass the —sysroot= option to gcc , where is the system root of your target system
- Build gcc and binutils to use as their default sysroot
The latter approach is the one that Angstrom uses, and it save a lot of butt-hurt.
Источник
Cross Compiling Linux Arm Kernel with new driver module
I am trying to include a driver for use on my arch linux arm machine. I tried using these steps to include the driver module, but my cross-compiled kernel with the added driver doesn’t load.
Then when my embedded linux arm tries to load the kernel uImage, it hangs with: EDIT: Changed the entry point address to 80008000, so now it hangs with:
Bytes transferred = 3174848 (3071c0 hex)
Booting kernel from Legacy Image at 81800000 .
Image Name: 2.6.35-ModifiedEntry
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 3174784 Bytes = 3 MiB
Load Address: 80008000
Entry Point: 80008000
Verifying Checksum . OK
Loading Kernel Image . OK
OK
Am I cross-compiling my kernel wrong? It cannot load the uImage. All I want to do is cross compile my kernel for the linux arm machine with a newly included driver (included in the config from make menuconfig). Am I missing any additional steps?
1 Answer 1
You have done two mistake in kernel building procedure.
1)before make menuconfig
you need to have a .config file should exit in source-code.
How u can get it
1) make ARCH=arm board_defconfig
check your default config in /arch/arm/configs
e.g make ARCH=arm versatile_defconfig
this will write default configuration to .config
2)if you dont know your default configuration you can get it in target board Filesystem.
it will be in /proc/config.gz copy to your host untar it and copy as .config in top source-code. or it may present in /boot/config.x.x.x
if dont follow above step make ARCH=arm menuconfig this will copy host x86 config file from /boot/config-x.x.x which will be wrong config file
Once above step is done then next step make ARCH=arm menuconfig here enable your driver.
2nd mistake is make ARCH=arm CROSS_COMPILE=/home/z3/bin/arm- modules_install
This will install modules in /lib/modules of x86 host machine.
so follow below one
make ARCH=arm CROSS_COMPILE=(path to arm) uImage modules
create a directory to install your dynamic loadable modules
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- modules_install INSTALL_MOD_PATH=
Then you need to copy modules to your target.
For more details you can refer this Just black screen after running Qemu
Источник
Cross compiling Linux Kernel drivers
Feb 12, 2017 · 2 min read
For every patch sent for a Linux kernel driver one needs to be sure that the .o file has been obtained after compiling the changed .c file. A driver can contain a mixture of files that are meant for different machine architectures like blackfin, arm, sparc, mips, x86 etc. It might happen that a .c file written for arm architecture might not compile on my machine which is based on a x86 architecture. To solve this problem and to send a patch for arm architecture based files from my machine, I need to cross compile the files for arm.
W h enever the command “make “ is run, all the .c and headers are compiled and the corresponding .o files are obtained. But as mentioned above some files that are written for a different architecture might not compile on x86 or some other architecture based machine. In that case the .o file will not be obtained.
When an individual .o file is compiled using the command “make
”, the file either compiles or gives a compilation error. Below is one such case I encountered some weeks ago. I ran the command: make drivers/remoteproc/da8xx_remoteproc.o but I got the following error as the file is not meant to compile on x86.
When I ran “make drivers/remoteproc/” the driver compiled without any errors but then I did not get the drivers/remoteproc/da8xx_remoteproc.o file after compilation. So, to be completely sure of the changes always cross compile the changed files.
But then how to do it?
My mentor Julia has sent me a make.cross script that cross compiles the .o files on any machine irrespective of its architecture. Save this script to the kernel’s git repo and follow these steps.
Below are the steps to cross compile a file:
- Go to the makefile of the sub driver or the parent directory and find the configuration symbol for the .o file.
- For the above case the makefile in drivers/remoteproc/ driver has this line for the drivers/remoteproc/da8xx_remoteproc.o file: obj-$(CONFIG_DA8XX_REMOTEPROC) += da8xx_remoteproc.o
- Now grep for the configuration symbol CONFIG_DA8XX_REMOTEPROC in arch/ and find the architecture where this symbol is located. For this case it is there in arch/arm/mach-davinci/devices-da8xx.c file.
- This shows that the architecture is ‘arm’. Now run: make.cross ARCH=arm allyesconfig; make.cross ARCH=arm drivers/remoteproc/da8xx_remoteproc.o. This should compile the .o file.
It may happen that the .o file will still not compile because some other configurations are also needed. In such a case send the patch but do mention that the .o file could not be obtained and the developers will surely provide a way to cross compile the driver and the .o file.
Источник