29 KiB
Сборка ядра Linux для Orange Pi 5 Plus (и других устройств на Rockchip RK3588) с поддержкой iSCSI
Для моего проекта (k3s на Orange Pi 5 Plus) потребовалась поддержка система управления блочным хранилищем 'longhorn' (longhorn.io). Longhorn позволяет создавать надёжные тома для контейнеров, автоматически реплицируя их между узлами и обеспечения высокую доступности приложений (если один узел выходит из строя, данные остаются доступны на репликах на других узлах).
Для longhorn нужен iSCSI
(Internet Small Computer System Interface) — сетевой протокол, который по TCP/IP
подсоединяет удалённые диски так, будто они подключены физически. Longhorn через iSCSI обеспечивает передачу
данных между узлами по сети.
В ядре Linux поддержка iSCSI реализована через модули, такие как iscsi_tcp
и scsi_transport_iscsi
. Однако,
в большинстве дистрибутивов для одноплатных компьютеров, включая и Orange Pi 5 Plus, эти модули отключены. Это делают
для экономии ресурсов, да и в целом, это нетипичный сценарий использования Orange Pi. В версии Ubuntu 22.04
для Orange Pi 5 Plus (в ядре от Xunlong), поддержка iSCSI тоже отключена, и это делает невозможным запуск Longhorn
из коробки.
А значит нужно компиляция ядра (сбока)
Мы вручную включим поддержку iSCSI (модули iscsi_tcp
и scsi_transport_iscsi
), и cможем настроить
ядро под свои задачи. Однако компиляция и его замена требует осторожности и внимательности, ошибка в процессе может
привести к тому, что система не загрузится (но мы сделаем резервную копию текущего ядра, загрузчика, чтобы можно
было восстановить систему).
Обновления системы (например, через apt
) с новым ядром будет проходить, как обычно: пакеты, утилиты и приложения
обновятся без проблем. Однако пересобранное ядро больше не будет автоматически обновляться через стандартные средства
дистрибутива. Если выйдет новая версия ядра, то придётся вручную повторить процесс компиляции. К счастью,
поставщик (это Xunlong) обновляет ядро не часто.
✎ Заметка |
---|
Orange Pi 5 Plus использует процессор Rockchip RK3588 (как и многие другие устройства под брендом Orange). Процесс компиляции ядра для всех RK35xx почти идентичен, и базируется на одном и том же дистрибутиве. Однако, разные периферийные устройства: например, GPIO, USB или Ethernet-контроллеры могут отличаться. Мы будем использовать .config от текущего, рабочего ядра, так что настройки будут актуальны. Но следует иметь в виду, что возможно, в будущем могут появиться изменения в конфигурации, дистрибутива и т.п. Следует учитывать, это и никто ничего не гарантирует. |
План сборки ядра с iSCSI
- Резервное копирование текущего ядра, загрузчика, дерева устройств, /boot и т.п.
- Установить инструментарий для настройки и компиляции ядра
- Скачать исходники.
- Настроить конфиг для включения модулей iSCSI (и мониторинга NVMe).
- Скомпилировать ядро и модули.
- Установить новое ядро.
- Перезагрузиться в новое ядро.
- Проверка.
Резервное копирование текущего ядра и /boot
Архивируем том /boot
на нашем Orange Pi 5 Plus во временный каталог /tmp
:
sudo tar -czf /tmp/boot-backup.tar.gz /boot
Проверим, что архив создался:
ls -al /tmp/boot-backup.tar.gz
Увидим что архив создался:
-rw-r--r-- 1 root root 62116591 мар 23 20:33 /tmp/boot-backup.tar.gz
Теперь нам нужно скопировать его на какой-нибудь внешний хост (или носитель, но я буду копировать на хост другого
компьютера). Если что-то пойдёт не так (например, после обновления ядра система не загрузится) можно будет восстановить
файлы из этого архива. Мой Orange Pi 5 Plus, на котором я буду компилировать ядро имеет хост — opi5plus-3
(замени
на свой хост), а имя пользователя от которого я работаю — opi
(замени на свой). На рабочем компьютере, с которого
я захожу по SSH на Orange, у меня есть папка ~/backup/
(mkdir -p ~/backup
). Скачиваю в неё архив:
scp opi@opi5plus-3.local:/tmp/boot-backup.tar.gz ~/backup/opi5plus-3-boot-backup.tar.gz
Что в архиве?
Если что-то пойдет не так, нам надо знать какие файлы в /boot
важны и для чего предназначены. Вот список файлов
('ls -al /boot'):
drwxr-xr-x 4 root root 4096 янв 1 1970 ./
drwxr-xr-x 19 root root 4096 фев 16 19:59 ../
-rwxr-xr-x 1 root root 230456 ноя 21 09:56 boot.bmp*
-rwxr-xr-x 1 root root 3341 ноя 21 09:55 boot.cmd*
-rwxr-xr-x 1 root root 3413 ноя 21 10:04 boot.scr*
-rwxr-xr-x 1 root root 230393 ноя 21 07:08 config-6.1.43-rockchip-rk3588*
drwxr-xr-x 3 root root 4096 ноя 21 09:55 dtb/
drwxr-xr-x 3 root root 4096 ноя 21 09:55 dtb-6.1.43-rockchip-rk3588/
-rwxr-xr-x 1 root root 40579584 ноя 21 07:08 Image*
-rwxr-xr-x 1 root root 15462140 мар 21 16:36 initrd.img-6.1.43-rockchip-rk3588*
-rwxr-xr-x 1 root root 1152056 ноя 21 09:56 logo.bmp*
-rwxr-xr-x 1 root root 0 ноя 21 09:55 .next*
-rwxr-xr-x 1 root root 178 фев 16 19:59 orangepiEnv.txt*
-rwxr-xr-x 1 root root 1542 ноя 21 09:56 orangepi_first_run.txt.template*
-rwxr-xr-x 1 root root 6209932 ноя 21 07:08 System.map-6.1.43-rockchip-rk3588*
-rwxr-xr-x 1 root root 15462204 мар 21 16:36 uInitrd*
-rwxr-xr-x 1 root root 40579584 ноя 21 07:08 vmlinuz-6.1.43-rockchip-rk3588*
Ключевые файлы:
Image
— собственно ядро Linux (в данном случае версия 6.1.43 для Rockchip RK3588). При старте компьютера загрузчик U-Boot загрузит его в память и передаст ему управление. Без этого файла система не запустится.vmlinuz-6.1.43-rockchip-rk3588
— копия ядра (в системе уже есть резервная копия).dtb/
— Каталог файлами Device Tree Blob (DTB
). Это бинарные файлы, описывающие аппаратное обеспечение устройства. Для Orange Pi 5 Plus используется файл вродеrk3588-orangepi-5-plus.dtb
(находится в подкаталогеdtb/rockchip/
). DTB передаётся ядру, чтобы оно знало, как работать с процессором (количество ядер, частоты), памятью (RAM, её объём и адреса), периферией (UART, I2C, SPI, Ethernet, USB, GPIO, прерывания и тому подобное). На ARM-устройствах (в отличие от x86, где есть ACPI) нет стандартного способа обнаружения оборудования. DTB решает эту проблему, предоставляя ядру "карту" железа. U-Boot загружает DTB из/boot/dtb/
и передаёт его ядру при старте. Кстати, в подкаталоге dtb/rockchip/ естьoverlay/
— это дополнительные файлы, которые могут использоваться для добавления и/или изменения функциональности устройства. Например, можно добавить поддержку новых периферийных устройств (камеру, дисплей и т.п.).uInitrd
— Начальный RAM-диск (initrd), адаптированный для U-Boot. Содержит модули и скрипты, необходимые для пред-загрузки (выбор накопителя, монтирование корневой файловой системы и т.п.). Если он повреждён или несовместим с ядром, загрузка может упасть на этапе инициализации.orangepiEnv.txt
— Конфигурационный файл для U-Boot. Здесь задаются параметры загрузки, такие как путь расположение дерева DTB, UUID корневой файловой системы, тип файловой системы… Без правильных настроек в этом файле U-Boot не найдёт нужные для загрузки файлы.boot.scr
— Скрипт загрузки для U-Boot. Содержит команды для загрузки ядра, initrd и DTB. U-Boot выполняет его при старте системы. Этот файл создаётся изboot.cmd
с помощью утилитыmkimage
. Если он повреждён или отсутствует, U-Boot не сможет загрузить систему.dtb-6.1.43-rockchip-rk3588/
— Копия каталогаdtb/
, обычно появляется, когда ядро устанавливается или обновляется через пакетный менеджер (например,apt
). Она привязана к конкретной версии ядра — в данном случае6.1.43-rockchip-rk3588
, для того, чтобы: Хранить DTB-файлы, соответствующие этой версии ядра и избегать конфликты между DTB от разных версий ядра (если используется несколько ядер на одной системе).
Менее критичные, но полезные файлы:
config-6.1.43-rockchip-rk3588
— Конфигурация ядра, использованная при его сборке (он нам понадобится, чтобы пересобрать ядро с iSCSI).System.map-6.1.43-rockchip-rk3588
— Карта меток (символов) ядра, полезна для отладки.initrd.img-6.1.43-rockchip-rk3588
— Обычный initrd, из которого генерируется uInitrd.boot.bmp
иlogo.bmp
— Изображения для экрана загрузки (не влияют на работу системы).
Устанавливать инструменты для сборки ядра
Обновим репозитории и установим минимальный инструментарий для сборки ядра:
sudo apt update
sudo apt install -y build-essential bc flex bison libssl-dev libncurses-dev git
Нам понадобятся следующие пакеты:
build-essential
— Включаетgcc
(для ARM64, make и другие базовые инструменты компиляции.bc
— Утилита для точных математических вычислений в командной строке. Используется для вычислений в скриптах сборки ядра.flex
иbison
— генератор лексических анализаторов и парсер. Нужны для обработки конфигурационных файлов ядра.libssl-dev
— Для поддержки криптографии в ядре иOpenSSL
.libncurses-dev
— Библиотека для создания текстовых интерфейсов в терминале. Необходимо для работы интерфейсаmenuconfig
при настройке параметров ядра.git
— Для клонирования исходного кода ядра из репозитория Xunlong.
Примечание: Если вы хотите собрать ядро на x86-системе, установите кросс-компилятор
gcc-aarch64-linux-gnu
(sudo apt install gcc-aarch64-linux-gnu
) и используйте его вместо обычного gcc в командах сборки. Он позволит собрать ядро для ARM64-архитектуры на x86-системе.
Скачивание и подготавливаем исходники ядра
Клонируем репозиторий Orange Pi для ядра 6.1 из репозитория Xunlong. Мы будем брать ветку (branch)
orange-pi-6.1-rk35xx
. Это ветка с исходниками для всех устройств на базе Rockchip RK35xx (включая Orange Pi 5 Plus):
git clone --depth 1 https://github.com/orangepi-xunlong/linux-orangepi -b orange-pi-6.1-rk35xx ~/linux-orangepi
После клонирования репозитория, переходим в каталог с ним:
cd ~/linux-orangepi
И первым делом в Makefile
установим EXTRAVERSION
(модификатор версии ядра). Узнаем текущую версию ядра:
uname -r
Я на своем Orange Pi 5 Plus вижу (у вас может быть другая версия):
6.1.43-rockchip-rk3588
Открываем Makefile
в текстовом редакторе:
nano Makefile
И устанавливаем модификатор версии ядра, строку XTRAVERSION =
(у меня это пятая строчка):
EXTRAVERSION = -rockchip-rk3588
Затем копируем конфиг текущего ядра в конфиг для сборки.
zcat /proc/config.gz > .config
.config
содержит все текущие настройки ядра. Это очень удобно, так как нужно добавить только поддержку нужных модулей
(в нашем случае iSCSI
), а не настраивать всё с нуля.
Настройка конфига с iSCSI
Теперь нужно отредактировать, .config
чтобы включить iSCSI
. Заходим в интерфейс конфигуратора ядра menuconfig
:
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
Используя стрелки на клавиатуре, чтобы двигаться по пунктам меню.
- Перейди в
Device Drivers
→SCSI device support
→SCSI Transports
. - Найти внутри
iSCSI Transport Attributes
, с помощью стрелок выбрать его. - Нажимает
M
(для модуля) — появится<M>
рядом с пунктом. Это означает, что модуль будет собираться как модуль, а не встраиваться в ядро. Модуль (iscsi_tcp.ko
) проще протестировать без перезагрузки. - В нижнем меню выбрать
<Save>
и подтвердим сохранение в.config
. - Вернуться в меню выше
SCSI device support
(через нижнее меню<Exit>
). - Зайти в раздел
SCSI low-level drivers
. - Выбрать
iSCSI Initiator over TCP/IP
и нажатьM
(для модуля). - Снова сохраняем конфиг в
.config
(через нижнее меню<Save>
). - Выйти из
menuconfig
(через нижнее меню<Exit>
, три раза).
✎ Может быть полезно: |
---|
На моём Orange Pi 5 Plus загрузка идет с NVMe диска (см. как настроить), и мне было полезно так же включить ещё и систему мониторинга NVMe: Device Drivers → NVME Support , найти пункт SNVMe hardware monitoring и включить его. В нижнем меню выбрать <Save> и подтвердим сохранение в .config . Выйти из menuconfig (через нижнее меню <Exit> , три раза). Теперь у меня будет возможность отслеживать состояние NVMe-диска (температуру, износ и т.д.) через инструменты вроде nvme-cli . |
Проверим, что iSCSI включён:
grep -E "ISCSI_TCP|SCSI_ISCSI_ATTRS|ISCSI_BOOT" .config
Должны увидеть что-то типа:
CONFIG_SCSI_ISCSI_ATTRS=m
CONFIG_ISCSI_TCP=m
# CONFIG_ISCSI_BOOT_SYSFS is not set
✎ Проверка, что включен мониторинг NVMe (если включали): |
---|
grep -E "NVME_HWMON" .config и увидим CONFIG_NVME_HWMON=y |
Компиляция ядра и модулей
Запускаем компиляцию ядра и модулей:
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j8
-j8
— это количество потоков, используем столько, сколько у нас ядер. На Orange Pi 5 Plus восемь ядер. Но, например,
если у вас четыре ядра, то -j4
.
Компиляция займёт 20-40 минут (Orange Pi 5 Plus).
Установим модули ядра:
sudo make modules_install
После завершения ядро будет находиться в каталоге ~/linux-orangepi/arch/arm64/boot/
(файл Image
), а дерево описания
устройства в ~/linux-orangepi/arch/arm64/boot/dts/rockchip/
(наш файл для Orange Pi 5 Plus --
rk3588-orangepi-5-plus.dtb
, дле версий 5, 5 Max, AI, Ultra соответствующие файлы там же).
Проверим, что ядро скомпилировалось:
ls -l arch/arm64/boot/Image
Ожидаемый размер: около 40 МБ:
-rw-rw-r-- 1 opi opi 40579584 Mar 22 19:09 arch/arm64/boot/Image
Размер должен почти совпасть (или полностью совпадать) с размером текущего ядра:
ls -l /boot/Image
-rwxr-xr-x 1 root root 40579584 Nov 21 07:08 /boot/Image
И это не ошибка. Мы добавили только CONFIG_ISCSI_TCP=m
и CONFIG_SCSI_ISCSI_ATTRS=m
. Это подключит модули (iscsi_tcp.ko
),
но само ядро (Image
) почти не увеличивается, ведь .ko
-модуль iSCSI не встраивается в ядро (мы выбрали <M>
,
а не <*>
). Кроме того, Linux выравнивает размеры файлов по блокам (например, 4 Кб), и добавление
пары небольших модулей могут не повлиять на итоговый размер.
Устанавливаем новое ядро рядом со старым
Мы должны скопировать два файла в /boot
. Первый — это Image
. Это само ядро, и оно скомпилировалось в каталог
~/linux-orangepi/arch/arm64/boot/
. Второй файл — это rk3588-orangepi-5-plus.dtb
. Он находится
в ~/linux-orangepi/arch/arm64/boot/dts/rockchip/
. Как было сказано выше, это дерево описания оборудования
(Device Tree Blob), и нужно при загрузке ядра. Кстати, при компиляции мы получили .dtb
для всех моделей Orange Pi 5
(5, 5 Plus, 5 Max, AI, Ultra). Для моей модели (Orange Pi 5 Plus) нужен rk3588-orangepi-5-plus.dtb
, а вы можете
взять другой, для своей модели.
Копируем новые файлы в /boot
с уникальными именами (с суффиксом -iscsi
):
sudo cp ~/linux-orangepi/arch/arm64/boot/Image /boot/Image-iscsi
sudo cp ~/linux-orangepi/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dtb /boot/dtb/rockchip/rk3588-orangepi-5-plus.dtb-iscsi
Старое ядро и дерево описания переименуем (это будет резервная копия, с суффиксом -original
):
sudo mv /boot/Image /boot/Image-original
sudo mv /boot/dtb/rockchip/rk3588-orangepi-5-plus.dtb /boot/dtb/rockchip/rk3588-orangepi-5-plus.dtb-original
Устанавливаем новые ядро и дерево:
sudo cp /boot/Image-iscsi /boot/Image
sudo cp /boot/dtb/rockchip/rk3588-orangepi-5-plus.dtb-iscsi /boot/dtb/rockchip/rk3588-orangepi-5-plus.dtb
Важно: Не обновляйте
uInitrd
, если текущий работает, — его замена может сломать загрузку системы.
Все готово.
Перезагрузка в новое ядро
Тут все просто:
sudo reboot
Если что-то пошло не так и система не загрузилась
Если вы все делали правильно, то такого быть не должно. Но, тем не менее, если загрузка не произошла, то это может выглядеть двумя способами:
- Система зависает на этапе загрузки: синенький огонек на Orange Pi не загорается и Ethernet тоже не мигает — _вы неправильно собрали ядро или испортили загрузчик.
- Система, вроде как, грузится, но все никак… огоньки весело мигают, но не получается подключиться ни по SSH, ни
другим способом, пинги на IP-адрес не проходят — вы забыли подключить модули, накосячили с конфигом или с
.dtb
_.
Чтобы починить, загружайтесь с MicroSD-карты (не забудьте отключить питание перед тем как вставить MicroSD-карту). Затем смонтируйте, в зависимости где у вас система, eMMC:
mkdir -p /mnt/emmc
mount /dev/mmcblk2p1 /mnt/emmc
cd /mnt/emmc
…или NVMe:
mkdir -p /mnt/nvme
mount /dev/nvme0n1p1 /mnt/nvme
cd /mnt/nvme
И восстанавливаем старое ядро и дерево описания:
sudo cp Image-original Image
sudo cp dtb/rockchip/rk3588-orangepi-5-plus.dtb-original dtb/rockchip/rk3588-orangepi-5-plus.dtb
Выключаем систему:
sudo poweroff
Вынимаем MicroSD-карту, включаем, и загрузиться старая система.
Проверка нового ядра
Если же иситма поле обновления ядра загрузилась, проверим текущую версию ядра:
uname -r
Она должна остаться той же:
6.1.43-rockchip-rk3588
Проверим, работает ли iSCSI:
sudo systemctl status iscsid
Увидим что-то вроде:
● iscsid.service - iSCSI initiator daemon (iscsid)
Loaded: loaded (/lib/systemd/system/iscsid.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2025-03-24 17:51:59 MSK; 28min ago
TriggeredBy: ● iscsid.socket
Docs: man:iscsid(8)
Main PID: 1070 (iscsid)
Tasks: 2 (limit: 18977)
Memory: 4.6M
CPU: 94ms
CGroup: /system.slice/iscsid.service
├─1069 /sbin/iscsid
└─1070 /sbin/iscsid
мар 24 17:51:58 opi5plus-3 systemd[1]: Starting iSCSI initiator daemon (iscsid)...
мар 24 17:51:59 opi5plus-3 iscsid[1061]: iSCSI logger with pid=1069 started!
мар 24 17:51:59 opi5plus-3 iscsid[1069]: iSCSI daemon with pid=1070 started!
мар 24 17:51:59 opi5plus-3 systemd[1]: Started iSCSI initiator daemon (iscsid).
Как видим, active (running)
, значит iSCSI работает.
✎ Заметка |
---|
Если вы включили мониторинг NVMe, то проверим и его. Установим nvme-cli: sudo apt install nvme-cli и проверим состояние нашего накопителя sudo nvme smart-log /dev/nvme0n1 . |
ВСË!
А, да, не забудьте удалить репозиторий с исходниками ядра, если он вам больше не нужен:
rm -rf ~/linux-orangepi