http://ll.anew.su/personal/html/

posted: 01/01/2022 at 18:27:48
modified: 30/01/2022 at 10:57:33

Установка Slackware Linux, сборка ядра Linux для Orange pi plus 2

Введение

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

Задумал я подцепить к своей плате Orange pi, жесткий диск немного большего объема, дабы торрентам на нем не было тесно.

Отформатив его единственный раздел под xfs на ноуте и перекинув на него торренты со старого винта, я стартанул одноплатник. Однако, аккурат в этом месте, меня ждал облом.

То ли ядро у одноплатника оказалось слишком старое, то ли устарели тулзы для работы с xfs, то ли были еще какие причины, но факт в том, что нужный раздел упорно не желал монтироваться, выдавая ошибку xfs "bad superblock". Конечно же, на другой машине этот раздел монтировался без проблем. Значит, дело в софте, подумал я, и, почесав репу, решил, что пришло время для обновления системы.

Развертывание свежей сборки Slackware Linux.

Этот раздел предназначен для тех, кто будет ставить Slackware на "чистую" флешку.

Я же, просто обновил существующую систему до "current".

Итак, на рабочей машине загружаем из сети свежую сборку Armbian под нашу плату, записываем ее образ на sd-карту и запускаем с нее одноплатник.

Взять образы Armbian можно здесь.

В моем случае, мониторить процесс запуска удобно через USB UART-адаптер, используя программу minicom.

Запускается миником в Linux так:

minicom -D /dev/ttyUSB0

Таким образом, на одноплатнике мы имеем рабочую консоль (ttyS0). Это полезно, если на нем вдруг не работает сеть.

Но сеть у нас работает, так что можно подключиться и через ssh. Главное, знать ip-адрес платы.

Впрочем, проще всего подключить одноплатник к монитору посредством HDMI и использовать usb-клавиатуру для ввода, но тогда рабочая машина останется без монитора, а это, точно не наш метод!

Будем считать, что загрузка Armbian прошла штатно, произведены настройки первого запуска системы, и у нас есть консоль.

Размечаем или переразмечаем флешку.

Под Армбиан, флешка доступна как устройство mmcblk1 (но на другой плате может иметь иной номер).

Поэтому:

fdisk /dev/mmcblk1

Делаем там всякие свои дисково-разделочные дела, и в итоге, будем считать, что на флешке есть хотя бы один раздел, а именно, блочное устройство mmcblk1p1, объема, достаточного для размещения операционной системы. Для сервера без X Window System, с головой хватит 3-4 гигабайта.

Форматим этот раздел в нужную нам файловую систему. Пусть это будет ext4.

mkfs.ext4 /dev/mmcblk1p1

Монтируем наш раздел и переходим в каталог куда он смонтирован:

mount /dev/mmcblk1p1 /mnt

cd /mnt

Теперь, качаем свежий slack current miniroot отсюда.

Например:

wget http://ftp.arm.slackware.com/slackwarearm/slackwarearm-devtools/minirootfs/roots/slackarm-current-miniroot_14Jan22.tar.xz

На данный момент, пример не актуален, так как название архива minirootfs часто меняется.

Распаковываем скачанный файл:

tar xf slackarm-current-miniroot_14Jan22.tar.xz

Обязательно убираем за собой:

rm slackarm-current-miniroot_14Jan22.tar.xz

Вуаля! От сих пор, на флешке у нас развернутая ОС Slackware в своем минималистическом состоянии.

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

Das U-boot - the Universal Boot Loader. Сборка и установка загрузчика.

Для пущего удобства, подключаемся под пользователем root по ssh, на ip-адрес, который выдается одноплатнику роутером.

Вся работа далее будет проделываться от рута, поскольку в данном случае нет никакого смысла играться с sudo.

По умолчанию, root-логин на Армбиан через ssh разрешен.

Собственно, соберем U-boot.

Для начала, определимся, под какой системой будет происходить сборка, ведь на данным момент, их две!

Если сборка U-boot будет выполняться под Армбиан, то можно сразу переходить к соответствующему разделу повествования.

Если же сборка планируется в системе Slackware, то необходимо проделать следующее:

1. Примонтировать раздел содержащий корневую файловую систему Slackware в какой-нибудь каталог, например, /mnt.

mount /dev/mmcblk1p1 /mnt

2. Смонтировать виртуальные файловые системы в корневой раздел Slackware.

mount --bind /proc /mnt/proc/

mount --bind /sys /mnt/sys/

mount --bind /dev /mnt/dev/

3. Наконец, сменить корневую файловую систему.

chroot /mnt

После проделанных манипуляций, можно работать в Slackware с ядром от Армбиан. Устанавливать и удалять пакеты используя slackpkg (например, установить необходимые средства разработки, такие как gcc), компилировать софт, вносить изменения в файлы конфигурации (например, fstab).

Итак, мы определились с системой.

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

Можно собирать софт на внутренней mmc-флешке, а можно и на sd-карте. По идее, на флешке процесс пройдет быстрее, но это не точно. Следует также учесть, что после распаковки, исходники ядра и загрузчика, имеют довольно-таки внушительный "вес", поэтому для их компиляции, на флешке надо иметь не менее 2-2,5 Гб свободного "пространства". Обычно, архиватор способен сжимать текст в 10 и более раз. Т.е. если архив с исходниками занимает 150 Мб, то после распаковки, данные будут занимать более полутора гигабайт на носителе.

Берем свежий релиз исходников U-boot с ftp-сервера проекта ftp://ftp.denx.de/.

Качаем как обычно, с помощью wget. Например:

wget ftp://ftp.denx.de/pub/u-boot/u-boot-2022.01.tar.bz2

Затем распаковываем:

tar xf u-boot-2022.01.tar.bz2

Распакованный архив можно сразу потереть за ненадобностью. Переходим в распакованный каталог с исходниками U-boot.

cd u-boot-2022.01

Здесь, в каталоге configs необходимо найти название своей платы и создать .config для последующей компиляции загрузчика.

Чтобы быстрее найти название своего конфига в каталоге configs, делаем:

ls configs |grep orange

Данная команда отфильтрует все конфигурационные файлы, в названии которых содержится "orange".

В моем случае, я делал так:

make orangepi_plus_defconfig

Эта команда создаст дефолтный .config для сборки U-boot под указанную плату.

После создания конфига, особо продвинутые пользователи могут дать команду make menuconfig и сконфигурировать будущий загрузчик по своему вкусу.

Для тех кто все же решил заглянуть в конфигуратор, пусть ради любопытства, не лишним будет найти раздел "ARM architecture" и посмотреть там значение параметра "mmc extra slot number". По дефолту для моей платы, он равен "2". Это значит, что флешка mmc в системе будет доступна как блочное устройство mmcblk2. Именно этот номер блочного устройства должен передаваться ядру Linux в качестве аргумента при загрузке. SD-карта же, в моем случае, останется доступна через mmcblk1.

Значит, рутовый раздел будет mmcblk2p1, на котором располагается сама ОС Slackware.

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

Все. Можно приступать к сборке. Для этого достаточно выполнить "make".

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

Если сборка происходит на платформе Armbian, то устанавливаем или обновляем пакеты с помощью apt-get.

Если на флешке была развернута Slackware из miniroot, то используем менеджер пакетов slackpkg.

Итак, будем считать что наш загрузчик собрался, и в результате у нас появился нужный бинарник: u-boot-sunxi-with-spl.bin

Это и есть наш загрузчик в зародыше, который надо записать на загрузочное устройство. В моем случае, это mmc-флешка, распаянная на плате Orange pi.

Записываем загрузчик на место с помощью dd, следующей командой:

dd if=u-boot-sunxi-with-spl.bin of=/dev/mmcblk2 bs=1024 seek=8

Загрузчик собран, установлен и к разврату готов!

Переходим к сборке ядра.

Сборка mainline ядра Linux.

Процесс сборки софта уже был достаточно подробно описан на примере U-boot, поэтому при сборке ядра Linux, я опущу всякие подробности.

Точно так же, качаем и распаковываем исходные коды ядра c kernel.org.

wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.16.tar.xz

tar xf linux-5.15.16.tar.xz

rm linux-5.15.16.tar.xz

cd linux-5.15.16

Для того чтобы правильно сконфигурировать будущее ядро, создадим дефолтный конфиг, по типу того, как это было сделано для U-boot.

make sunxi_defconfig

Готовый файл конфигурации помещается в корень исходных кодов и носит гордое но простое название ".config".

Файлы дефолтных конфигов находятся в каталогах конкретной архитектуры. В моём случае, это "arch/arm/configs".

В принципе, даже если скомпилировать ядро с такой конфигурацией, оно уже заработает.

Но, поскольку мне нужно маленькое и шустрое ядро, заточенное под мои нужды, я убираю из него все лишнее, а также добавляю поддержку необходимого железа. Ссылка на уже готовый ".config" для Orange pi plus 2 находится в самом конце статьи.

Для визуального конфигурирования будущего ядра, выполняем:

make menuconfig

Чтобы правильно скофигурировать ядро, необходим определенный опыт, который каждый получает сам. Поэтому всем, кто занимается сборкой ядра, я лишь пожелаю удачи и терпения.

Не лишним будет также выполнить "make help" и ознакомиться со всевозможными целями для сборки.

Что ж, конфигурация выполнена, изменения сохранены, настало время сборки.

Если охлаждение процессора активное, то для ускорения процесс сборки можно производить сразу на 4 ядрах.

Указываем это компилятору директивной "-j 4":

make -j 4 zImage

Если охлад пассивный, то лучше не перегревать проц и ограничиться парой ядер. Однако, в этом случае, процесс cборки ощутимо замедлится. Я собирал ядро в два потока, и температура процессора не превышала 50 градусов по Цельсию без активного охлаждения.

Ядро собрано, переходим к модулям и их установке:

make -j 2 modules && make modules_install

Модули собраны и установлены. Копируем готовое ядро в каталог "/boot" рутовой файловой системы, откуда его в дальнейшем будет брать загрузчик:

cp arch/arm/boot/zImage /boot

Собираем дерево "устройств" с флагом, необходимым для применения оверлеев на этапе загрузки:

make -j 4 DTC_FLAGS="-@" dtbs

Эта команда соберет все файлы устройств, подходящих под указанную в конфигурации ядра архитектуру.

Выбираем файл под свою плату и копируем туда, где его отыщет U-boot. Например:

cp arch/arm/boot/dts/sun8i-h3-orangepi-plus.dtb /boot/dtb

Расположение файла дерева устройств указывается загрузчику в файле boot.scr, поэтому, его можно поместить практически где угодно.

Подробнее об оверлеях и с чем их едят, я рассказал в статье: Оверлеи в Linux. Device tree overlays for Orange Pi plus 2.

На этом, сборку ядра можно считать завершенной.

Остается последний этап работы. А именно, сборка рамдиска и конфигурирование того самого загрузчика U-boot.

Конечно, можно вовсе обойтись без рамдиска, но его использование, считается хорошим тоном.

Создание образа рамдиска initrd (uInitrd) и сценарий загрузчика boot.scr

Initrd, он же Initial RAMDisk - не что иное как корневая, виртуальная файловая система минимального размера, в некоторых случаях, необходимая для запуска Linux. Располагается она, как следует из названия, в оперативной памяти.

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

Собираем рамдиск.

Для этого переместимся непосредственно туда где он будет располагаться и соберем его:

cd boot

mkinitrd -c -k 5.15.16 -f ext4 -r /dev/mmcblk2p1 -u -o /boot/initrd.gz

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

В Slackware, установка утилиты для сборки initrd (mkinitrd), выполняется следующей командой:

slackpkg install mkinitrd

Готово. На выходе получаем initrd.gz - слепок виртуального диска, тщательно обработанный со всех сторон утилитами gzip и cpio в лучших традициях UNIX.

Однако, простой сборки рамдиска мало. Чтобы u-boot смог загрузить рамдиск в память, его необходимо подготовить.

Для создания образа (в старом формате), выполняем:

mkimage -A arm -T ramdisk -C none -n uInitrd -d initrd.gz uInitrd;

Утилита mkimage дописывает свой заголовок (содержащий информацию об архитектуре, методе сжатия, адресе точки входа и т.п.) к началу initrd.gz, после чего, U-boot может его использовать.

Чтобы использовать mkimage в Slackware, необходимо установить пакет u-boot-tools:

slackpkg install u-boot-tools

Впрочем, готовую mkimage можно найти и в каталоге tools, который, в свою очередь, находится в исходных кодах проекта U-boot. Утилиты из каталога tools, компилируются в процессе сборки U-boot.

Дополнительная информация по созданию рамдиска, находится здесь

boot.cmd и boot.scr

Последнее, что необходимо для полноценной работы одноплатника, это скрипт загрузки системы - boot.scr.

Что такое этот boot.scr? Это сценарий, который выполняет загрузчик U-boot. По-сути, это текстовый файл с бинарным заголовком. При загрузке, U-boot ищет этот скрипт в корне раздела или директории /boot. Я использую второй вариант, и размещаю boot.scr в каталоге /boot.

Формируется данный скрипт точно так же, как и uInitrd. Т.е. с помощью утилиты mkimage.

Например, наш скрипт находится в директории /boot и имеет имя boot.cmd. Для преобразования скрипта в формат понятный U-boot, выполним следующую команду:

mkimage -C none -A arm -T script -d boot.cmd boot.scr

Что касается содержимого boot.cmd, то это дело вкуса каждого. Примеры скрипта (и множество иной информации для линейки arm-процессоров Allwinner) можно найти на страницах сайта https://linux-sunxi.org/.

Список аргументов для сценария, которые U-boot передает ядру Linux, находится там же.

Подробный boot.cmd можно взять все в том же проекте Armbian и модифицировать его под свои нужды. В общем, информации и примеров в сети множество.

Пожалуй, на этом все. Разве что, добавлю немного про cpufreq.

Почему не работает cpufreq?

Во всяких статьях и инструкциях, а равно как и в фильмах, все выглядит гладко и красиво. Но на практике, редко что-то получается сразу и хорошо.

Вот и у меня в процессе сборки ядра, возникли некоторые нюансы. Речь идет об управлении частотой процессора. Конкретно, о cpufrequtils. Этот пакет программ предназначен для изменения частоты процессора налету, в зависимости от нагрузки на систему или схемы энергосбережения.

В моем случае, cpufreq просто не работал. Причина была в банальном отсутствии драйвера микросхемы-регулятора напряжения. Микросхема SY8106A распаянная на плате Orange pi plus, управляется по шине i2c и необходима для регулировки напряжения процессора. Ее достаточно просто обнаружить на шине i2c с помощью утилиты i2cdetect на втором контроллере шины по адресу 0x65.

После сборки соответствующего модуля, cpufreq заработал как надо.

Заключение

Здесь хочется написать о том, что вся затея с пересборкой ядра, оказалась, в общем-то, ненужной, ведь жесткий диск так и не смонтировался после всех манипуляций.

Причина банальна. Дешевый USB to SATA конвертер, именуемый по рождению GL830 и эмулирующий SATA-порт на плате - сообщал ядру неверные данные о физическом объеме жесткого диска. Вследствие чего, файловая система не могла быть смонтирована.

Проблему я решил простым уменьшением количества секторов в разделе. Ну что же, бывает...

P.S.: Kernel config

А обещанный файл конфига ядра, здесь:

В глазах - обида, в руках - утюг