Назад
NixOS на Steam Link: саморобний модуль kexec обходить ядра Valve із підписом
SiTech AI Team3 წთ. საკითხავი

NixOS на Steam Link: саморобний модуль kexec обходить ядра Valve із підписом

Джордж Хюбнер перетворив Steam Link, куплений на розпродажі 2018 року, на постійно ввімкнений ARM-сервер. Оскільки пристрій завантажує лише ядра, підписані Valve, він зібрав мінімальний модуль ядра, який додає відсутній виклик kexec, і передав йому завантаження NixOS.

Джордж Хюбнер знайшов у шафі Steam Link, куплений ще 2018 року на розпродажі, який досі справно працював, і вирішив, що невеликий ARM-пристрій з Ethernet, Wi-Fi, Bluetooth і кількома USB-портами стане корисною машиною, яка ніколи не вимикається. У дописі, опублікованому 26 вересня 2026 року, він розповідає, як запустив на ньому NixOS і який трюк із модулем ядра це уможливив.

Складну частину вже розв'язав ентузіаст під псевдонімом fijam, чиї нотатки автор згадує. Головна перешкода: завантажувач пристрою приймає лише ядра, підписані Valve, тож власне ядро напряму не запустити. Обхідний шлях такий: завантажитися в схвалене Valve ядро, а потім зробити kexec у нове.

Системний виклик, зібраний як модуль ядра

Тут постає друга стіна: ядро, яке постачає Valve, зібране без CONFIG_KEXEC, тому системного виклику kexec у системі просто немає. Автор зібрав відповідні вихідні файли kexec у мінімальний модуль ядра kexec_load.ko, який додає зниклий виклик до працюючої системи. Цей самий прийом уже використовували, щоб завантажувати інші дистрибутиви, але здебільшого люди просто завантажували готовий модуль і бінарник kexec із сайту fijam. Хюбнер не хотів тягнути модулі ядра з інтернету й зібрав усе сам.

Крос-компіляція під 13-річне ядро

Зібрати простір користувача, ядро та initrd для NixOS нескладно: достатньо передати lib.nixosSystem правильні system і crossSystem. З архітектурою було складніше. Інструментарій Valve орієнтований на armv7a, але відповідне налаштування crossSystem, armv7a-unknown-linux-gnueabihf, погано взаємодіє зі збиральним механізмом Go у Nix, тож автор узяв armv7l і крос-компілював з aarch64-машини. Сам модуль потрібно збирати проти вбудованої гілки 13-річного ядра Valve, версії 3.8.13: для сучасного GCC знадобилися патчі, а також повне складання ядра, а не лише make modules_prepare, бо версіонування модулів вимагає Module.symvers, без якого insmod відхиляє модуль.

Навпомацки, а потім стиснення образу

Перевірити передачу керування було непросто. HDMI на новому ядрі не працює, а розбирати пристрій заради UART автор не став, тож спершу використав мінімальний initramfs на BusyBox, який писав на диск файл-маркер і перезавантажувався як сигнал успіху. Пізніше він перейшов на initrd NixOS із увімкненою мережею та зворотною оболонкою через Netcat. Дві деталі виявилися критичними: до доступних модулів initrd довелося додати reset_berlin, щоб читати USB-накопичувач, і використати старіший initrd без systemd. Після успішного завантаження образ усе ще важив 2,3 ГБ, тож автор прибрав документацію, шрифти, служби XDG, сам Nix і всі мікропрограми з 1,8-гігабайтного пакета linux-firmware, крім однієї, і зупинився на 1,2 ГБ, назвавши результат достатньо добрим. Наприкінці він зауважує, що хтось інший нещодавно «навайбив» завантажуваний конфіг NixOS, але той неправильно поводиться з перезавантаженнями й тягне зайві бінарні блоби. Вихідний код flake і модуля опубліковано разом із дописом.

SSiTech

SiTech — веброзробка з підтримкою AI

Створюємо швидкі та сучасні сайти й інтегруємо AI у бізнес-процеси. Маєте проєкт чи запитання? Із задоволенням допоможемо.