Зачем?
Наверное многие опытные линуксоиды скажут вам, что собирать своё ядро - занятие весьма неблагодарное: его нужно поддерживать и пересобирать под новые версии. Лучше всё-таки пользоваться свежими уже собранным ядрами, идущими в комплекте с дистрибутивом.
Но бывают случаи, когда вам нужно поддержать какое-нибудь экзотическое оборудование, которого нет в стандартном ядре. В моём случае, это китайский 4.3-дюймовый дисплей WaveShare, который не заработал из коробки.
Ставим toolchain
Toolchain - набор утилит, позволяющий собирать на вашем x86 компьютере код для процессора ARM (для BeagleBone).
Самый простой вариант - поставить пакеты из репозитория вашего дистрибутива:
sudo apt-get install binutils-arm-linux-gnueabihf g++-arm-linux-gnueabihf cpp-arm-linux-gnueabihf
НО! У вас установится GCC пятой версии, с которым ядро 3.8.xx не соберётся!
Поэтому лучше всего брать toolchain от сообщества linaro. Заходим на сайт и скачиваем уже готовые бинарники, которые нужно только распаковать:
http://releases.linaro.org/components/toolchain/binaries/4.9-2016.02/arm-linux-gnueabi/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabi.tar.xz
Распаковываем их, допустим в директорию /home/user/bb/gcc-linaro-4.9
Где брать ядро Linux для BeagleBone
Для получения ядра у вас должен быть установлен GIT.
Клонируем репозиторий с ядром:
cd linux
Переключаемся на ветку с ядром 3.8.xx
Сборка ядра Linux для BeagleBone
Собираем конфигурацию по умолчанию
make ARCH=arm CROSS_COMPILE=/home/user/bb/gcc-linaro-4.9/bin/arm-linux-gnueabihf- bb.org_defconfig
Обратите внимание, т.к. toolchain у нас установлен не в систему, а просто распакован в отдельную папку, то нужно указывать полный путь к бинарникам компилятора.
Непосредственно сама сборка, для ускорения запущенная в 4 потока:
make ARCH=arm CROSS_COMPILE=/home/user/bb/gcc-linaro-4.9/bin/arm-linux-gnueabihf- -j4
И создание образа ядра:
make ARCH=arm CROSS_COMPILE=/home/user/bb/gcc-linaro-4.9/bin/arm-linux-gnueabihf- uImage dtbs LOADADDR=0x80008000 -j4
Обратите внимание на адрес загрузки ядра! Если его неправильно указать, то новое ядро грузиться не будет! По этому адресу обращается загрузчик U-Boot при старте системы. Всё зависит от вашей операционной системы. В моём старом Debian задать его никак нельзя. И посмотреть тоже, кроме как подключившись адаптером USB->UART к дебажному COM-порту, прервать загрузку U-Boot и посмотреть его переменные (команда printenv). Приходится только гадать и подбирать.
Возможные значения: 0x80008000, 0x80000000, 0x88000000, 0x82000000.
Далее собираем модули ядра:
make ARCH=arm CROSS_COMPILE=/home/user/bb/gcc-linaro-4.9/bin/arm-linux-gnueabihf- modules -j4
устанавливаем их в отдельную папку:
make ARCH=arm CROSS_COMPILE=/home/user/bb/gcc-linaro-4.9/bin/arm-linux-gnueabihf- INSTALL_MOD_PATH=/home/user/bb/rootfs_3.8 modules_install
Ядро готово. Остаётся его только скопировать на BeagleBone.
Установка нового ядра на BeagleBone
Большинство руководств по сборке ядра предполагает его загрузку по tftp. Конечно, это немного сокращает время на проверку очередного ядра. Но требует довольно длительной настройки tftp-сервера на вашем компьютере и загрузки в Uboot-консоли через tftp. На мой вгляд гораздо проще лишний раз вставить карту памяти и залить ядро на неё.
Монтируем sd-карту памяти с файловой системой биглбона, допустим, в /media/user/rootfs/
Копирование модулей ядра
Заходим в /home/user/bb/rootfs_3.8/lib/modules и смотрим как называется наше ядро. В моём случае там папка 3.8.13+. Это и есть имя ядро.
Под рутом копируем эту папку в /media/user/rootfs/lib/modules. То же самое делаем и с папкой /lib/firmware, правда прошивки устройств сразу для двух версий ядра иметь не получится: нужно переименовать старую /lib/firmware и скопировать туда новую папку.
Копирование запакованного ядра
Бинарник ядра будет лежать по адресу /home/user/bb/linux/arch/arm/boot/uImage. Называем его по имени ядра (чтобы не перетирать текущего ядра BeagleBone): vmlinuz-3.8.13+ и копируем в /media/user/rootfs/boot.
Следующим этапом нужно скопировать файлы дерева девайсов (DeviceTree позволяет на ходу переключаться между различными функциями для каждой ножки биглбона: подключить UART, I2C или просто читать с ножки цифровой сигнал).
Копирование файлов DeviceTree для BeagleBone
Создаём папку с именем ядра /boot/dbts: /media/user/rootfs/boot/dbts/3.8.13+ и копируем туда файлы из /home/user/bb/linux/arch/arm/boot/dts. По сути, для биглбона нам нужнен только файл am335x-boneblack.dtb. Это файл, который содержит информацию о том, какими ножками процессора можно управлять через DeviceTree.
Копирование файлов CapeManager
CapeManager управляет различными платами расширения, а также с помощью него можно назначать на ножки биглбона разные фукнции (UART, I2C, GPIO, ADC).
Заходим в /home/user/bb/linux/firmware и копируем нужные *.dtbo файлы в /media/user/rootfs/lib/firmware.
К сожалению, это достаточно лишь для того, чтобы загружать *.dbto после загрузки ядра. Если вы изменили какой-то из файлов и хотите прописать его загрузку во время загрузки ядра, то придётся также копировать файл на initrd.img. Подробнее можно почитать здесь.
Обновляем конфигурацию Uboot
Под рутом открываем файл /media/user/rootfs/boot/uEnv.txt.
Прописываем новое имя ядра:
uname_r=3.8.13+
старую запись лучше заккоментировать (символ #) чтобы в любой момент можно было вернуться к родному ядру.
Послесловие
Если в статье что-то забыто, перепутано или неправильно, то не стесняйтесь оставлять комментарии.
P. S. возможно, перед сборкой ядра понадобится ставить дополнительный пакеты, всего я учесть не смог, т.к. поленился проделать всю процедуру с нуля на свежей виртуалке...