Сегодня только о Linux
Сборка ядра линуха на PC для PC не представляла, обычно, особых сложностей.
В период где-то с 2005 до 2015 я делал это неоднократно и схема всегда была довольно простой: качаем исходники ядра с сайта kernel.org (официальный сайт ядра), устанавливаем (если ещё не ставился) GCC и ещё кой какие пакеты (обычно перечисленные во всяких статьях и книжках). Потом распаковываем архив, делаем "make menuconfig" (при этом компилируется простенькая полноэкранная прога, которая позволяет настроить параметры ядра) и затем "make" - это уже компиляция ядра. На выходе получаем zImage - файл, который можно загрузить в память "пустой" машины разными загрузчиками, как автономными (типа lilo или grub), так и даже из под ms-dos (с выкидыванием ms-dos из памяти - привет агатовскому ПО).
Крайне редко бывало, чтобы этот процесс валился с какими-то ошибками.
Мороки было больше с настройками lilo или grub. Например, если нужна была какая-то замысловатая конфигурация загрузки: допустим, нужно было залить систему на пустой винт, который должен был в дальнейшем быть загрузочным, но подключенным на другой контроллер или другую позицию master/slave. В этом вопросе линух несколько менее очевиден, чем фряха.
К слову: ядро фряхи собирается примерно также, за исключением того, что там и настроек поменьше, так что их правят прямо в текстовом редакторе, в котором открыт файл конфига (файл небольшой, минут за 30 можно весь просмотреть, включая комментарии). И ставить для фряхи ничего не надо: source-base-операционка считает компилятор C неотъемлимой своей частью, как винда - свой IE.
Смысл кастомных ядер на PC был, в основном, в том, чтобы освободить ОЗУ: ядро грузится целиком в ОЗУ и если мильён драйверов в нём вам не нужны, то кастом позволяет резко уменьшить размер ядра. Актуально это было на компах с 8-32 Мб ОЗУ. И в дальнешем перестало играть существенную роль.
Разве что хотелось что нибудь этакого.... Ну, там, свой цвет системных сообщений или больше самодиагностики... Хотя многое из этого можно выкрутить настройками загрузки.
Для домашнего компа я также собирал фряху с двумя собственными патчами ядра:
1) снятие запрета на спецзначки в именах файлов на FAT (кавычки, звёздочки, вопросики..).
2) собственный формат таблицы разделов (когда был особо большой зоопарк операционок, уложиться в 4 записи MBR было сложно, кроме того была задача оградить некоторые ОС от возможности залезть в разделы других ОС, при этом сохранив классический MBR для M$-систем).
Года с 2015 всё стало немного шероховатее: бывает, что какая-то комбинация настроек внезапно приводит к сбою компиляции. Старожилы говорят, что так бывало и раньше, но я не сталкивался.
Эта проблема стала возникать и в линухе и во фряхе. Нередко это ошибки зависимостей: т.е. какая-то часть ядра A использует другую часть B, но в конфигураторе забыли указать эту зависимость A от B, в результате можно отключить сброку B при включенной сборке A. Но если в линухе это ошибка правил конфигуратора, то во фряхе ты вроде как сам правишь конфиг руками.... но порой трудно понять, как это самое A замысловато зависит от B.
--
Но когда делается кросс-компиляция (мне нужно собрать на PC ядро для ARM-A), всё происходит сложнее.
Кросс-компилятор включает в себя два набора элементов: компилятор + вспомогательные утилиты + ещё что нибудь для платформы сборки (т.е. x86), но также требуются и заголовки библиотек и всякое другое для целевой платформы (т.е. для arm). Если хотите статическую сборку (все библиотеки в один загрузочный файл), то, очевидно, нужны также и библиотки под целевую платформу.
Но и это ещё не всё: бывает так, что библиотеки со сложными, но легко автоматически проверяемыми алгоритмами (например, библиотеки расчёта хешей, архиваторы, шифрующее ПО, всевозможные аудио/видео конверторы и всякое такое) нередко пытаются в процессе сборки проверить сами себя. И у них это не получается: ведь мы собираем прогу для ARM, а работаем на PC: запустить собранную прогу или либу невозможно, разве что был бы какой-то стандартный механизм запуска внутри эмулятора.
Также бывает, что некоторые решения о правилах сборки проги выполняются на основании тестовой программки. Например, по логике работы прога должна в процессе работы сохранить рисунок. Она может сделать это используя разные графические библиотеки, но, по какой-то причине, выбор не может быть сделан только на основании наличия нужной библиотеки. Тогда сборщик пробует создать небольшую пробную программу, которая запишет (или не сможет записать) картинку с наиболее удачной библиотекой, если же этого не получается, то будет выбрана менее предпочтительная библиотека.
Доходит до того, что сборщик просит запустить какой-то тест на целевой платформе, а потом вписать в какой нибудь файл результаты теста (увы, не помню сейчас, в какой проге я с этим сталкивался).
Всё это (наборы компиляторов для целевой платформы, библиотеки, заголовки...) называется toolchain.
Существует две широко известных toolchain (от Linaro и от Yocto). И куча инструментов вокруг них (poky, bitbake...) назначения которых для меня самого пока тёмный лес (да, я читал wiki, но пока это не подержишь в руках - всё равно больше вопросов, чем ответов).
Есть цепочки и от производителей процов. Возможно, это модификации той же linaro или yocto - не знаю, не понял пока.
--
Если для PC кастомное ядро в нынешнее время - дело необязательное, то для ARM дело выглядит сложнее: можно, конечно, найти собранное ядро какой-то версии для вашего проца (скорее всего на сайте производителя этого проца), но, скорее всего, в него будет включено ВСЁ что поддерживает этот проц.
Дрова (и вся инфраструктура) дисплейного контроллера, тачскрина, ... в общем, всего, что только можно и даже с горкой (драйвера каких нибудь файловых систем, которые нам не нужны, и что-то подобное). В то же время оперативы у нас на борту планируется 256 Мб. Не мало, но и не много.
По моему опыту, сборка кастомного ядра для bridge3 может уменьшить размер arm-ядра примерно с 20 Мб до 10 Мб (в ОЗУ).
Вроде не много, но вроде и не мало. Это - очень примерные цифры.
/ Тут ещё нужно учитывать, что ядро хранится в архиве и распаковывается только при загрузке в память.
Архивация уменьшает время загрузки ОС, но не уменьшает используемое ОЗУ. /
Ну и, вот уже на примере SPI (но и не только его), явно видно, что без пересборки ядра тут тоже трудно выкрутиться. Вы всегда можете взять готовое ядро от какой нибудь девборды, но как только схемотехника вашей платы начнёт отдаляться от девборды - рано или поздно (особенно, если вы добавляете новые элементы) вам придётся собирать своё ядро.
--
Итак, я захожу на kernel.org и выбираю 5.10.93. Создаю конфигурацию под imx6 (там уже есть готовые патчи для главного конфига от производителей кучи ядер) и пытаюсь его собрать.
У меня стоит toolchain от MYiR, но им я собирал только ядра 4.x.
Тут же начинают вылезать проблемы: компиляция ещё не дошла до самого ядра, а процесс уже не может найти какие-то заголовки. Причем строка в исходнике выглядит так: '#include "expr.h"'.
Кто не знает C: имя в кавычках означает файл, находящийся где-то вблизи вашей проги, а не общесистемный (общесистемные записываются в <>).
Начинаю поиски этого expr.h. Везде: в toolchain, в гугле, в исходниках ядра. Нахожу их кучу.
Не ясно - какой из них нужен и почему сборщик его не находит.
Копаюсь в настройках утилиты make, выкручиваю из неё вывод команд, которые выполняются, выясняю, что поиск делается внутри toolchain, причем в заголовках host-библиотек. Дальнейшие раскопки показали:
перед тем, как начнётся сама сброка ядра, для GCC собираются плагины. Вы слышали когда нибудь, чтобы программа требовала для себя кастомизации компилятора ? Я - нет.
Да, у GCC есть механизм установки плагинов и ядру таки это нужно. Причем эти плагины входят в состав исходников ядра линуха. Чтобы их скомпилировать, нужны заголовки библиотек GCC.
Их нет в моей toolchain.
Я попробовал найти именно эти заголовки именно для моей версии GCC, закинул их в toolchain (а почему их там нет - подумалось мне?), но, в итоге, всё закончилось ошибкой линкера: т.е. этих заголовков нет, потому что связанный с ними функционал был исключён из сборки конкретного toolchain. Как его включить? Пересборать GCC именно этой версии заного........... Не, это слишком тёмный лес для меня.
Хорошо, лезу на сайты linaro и yocto, качаю тулчейны оттуда.
Скорее всего, Yocto я скачал не весь, но что именно нужно брать с сайта - лень разбираться.
Во всяком случае там был небольшой архив и явно много чего не хватало. Самого GCC я там не нашел.
С Linaro вроде бы было всё,... но не всё: попытки найти там файлы, которые не нашлись в моей цепочке, показали их отсутствие и тут.
Возможно, эта та самая кошка, которую ещё нужно уметь готовить.
Поэтому я залез в архивы MyIR и выкопал там новую версию их toolchain. С ней 5.10.93 тоже не собирается - опять не хватает очередного хидера. Но зато с ней стала собираться (и даже собралась, пусть и изредка с warning'ами) версия 5.4.3. Я не волшебник - я только учусь (и всю жизнь учиться буду).
5.4.3 - вполне неплохо. Не исключаю, что будут собираться и другие 5.4.x.
--
Что стало плохо в 5.x ядрах: раньше с ядром шел Readme, в котором прямо сообщались требования к среде сборки: "Make sure you have at least gcc 3.2 available". В 5.x даётся только ссылка на https://www.kernel.org/doc/html/latest/ - и сам там ищи, что нужно конкретно твоей версии. Я пока не нашёл. Там очень много инфы, но, в основном, по внутренней структуре ядра.
--
Да, это всё занимает кучу времени. Но, как говорят студенты: "Первые два года ты работаешь на зачётку, потом зачётка работает на тебя". Так же и здесь: если ядро заработает, оно сразу даст огромное количество фич, которые на bare metal пришлось бы строгать и строгать. Это и стандартная работа с устройствами через драйвера (таймеры, ethernet, usb, готовое ПО для сети, i2c,...) и отладка прог, включая остановку прог, совершивших что-то недопустимое (вместо зависания всей системы). И удалённое управление устройством (сеть, com-порт, ssh...). В общем, почти все те же плюшки, которые имеет разработчик на обычной PC.