Как поселить NixOS на Steam Link

· Linux и open source
Найдя в шкафу забытый с 2018 года Steam Link, разработчик решил превратить его в маленький ARM-сервер под управлением NixOS — и обошёл подпись загрузчика с помощью самодельного модуля ядра.

cover.svg

Разбирая шкаф, Джордж Хюбнер наткнулся на Steam Link, купленный по акции ещё в 2018 году и всё это время исправно работавший. Мысль напрашивалась сама собой: всегда включённое маломощное ARM-устройство с Ethernet, Wi-Fi, Bluetooth и несколькими USB-портами — отличная основа для домашнего сервера. Оставалось лишь поставить на него NixOS.

Обход подписи загрузчика

Основную сложность ещё раньше разобрал энтузиаст под ником fijam. Загрузчик Steam Link запускает только ядра, подписанные Valve. Обходной путь: загрузиться в благословлённое Valve ядро, а затем через kexec передать управление своему собственному. Беда в том, что штатное ядро собрано без CONFIG_KEXEC. Изящное решение — собрать нужные исходники kexec в отдельный модуль ядра, который добавляет системный вызов уже в работающую систему.

Многие просто копировали готовый бинарник и модуль с сайта fijam. Автор же не доверяет загруженным из сети модулям ядра и собрал всё сам.

Тринадцатилетнее ядро и старый GCC

Сборка пользовательского окружения и ядра NixOS проста, а вот выбор архитектуры оказался тоньше: инструментарий Valve использует armv7a, но с Go-сборкой он конфликтует, поэтому пришлось взять эквивалентный armv7l. Настоящим испытанием стала компиляция модуля для форка ядра версии 3.8.13-mrvl — ему тринадцать лет. Понадобилось несколько трюков, чтобы всё это собралось современным GCC.

Далее нужно было упаковать вместе initrd, ядро, device tree (он уже принят в апстрим Linux), статически собранный бинарник kexec и небольшой скрипт-связку. Готовый образ диска удобно собрать через модуль sd-image.

Отладка вслепую

Проверять работу kexec было мучительно: HDMI с новым ядром не работал, а вскрывать корпус ради UART автор не стал — то есть действовал совершенно вслепую. Сначала он загружал минимальный busybox-initramfs, который перезагружался через заданное время, сигнализируя об успехе. Затем перешёл на initrd NixOS с сетью и обратной оболочкой через netcat на ноутбук. Пришлось добавить модуль reset_berlin, чтобы читать USB-накопитель, и отказаться от нового systemd-initrd в пользу старого. В итоге — загрузка в пользовательское окружение и вход по SSH.

Диета для образа

Первый образ весил внушительные 2,3 ГБ. Оказалось, из гигантского пакета linux-firmware (1,8 ГБ в сжатом виде) нужен ровно один блоб для Marvell. Сам Nix на такой системе тоже почти бесполезен, так что и его выкинули. Дойдя до точки, где новые правки лишь ломали систему, автор признал образ в 1,2 ГБ «достаточно хорошим».

Уже перед публикацией он обнаружил, что кто-то другой «навайбкодил» загружаемую сборку NixOS — но с более неряшливой конфигурацией, некорректными перезагрузками и лишними бинарными блобами вместо сборки из исходников.


Источник: Lobsters

Комментарии

Войдите, чтобы комментировать.

  • Пока нет комментариев.