Компиляция Node.js из исходников для Xiaomi Mi Router 3G (OpenWrt)

Потребовалось мне установить Node.js на свой Xiaomi Mi Router 3G, прошитый под OpenWrt. В дефолтных репозиториях необходимого пакета не оказалось. Немного погуглив, были найдены всего пара источников (раз, два) в которых присутствовали нужные мне ipk файлы. Но, в первом случае они падали с ошибкой "Illegal instruction" (как позже выяснилось, для их работы необходимо пересобрать ядро с поддержкой MIPS FPU Emulator, о чем я расскажу ниже), а во втором версии были слишком старые (v8.17.0) и меня не устраивали (а если бы и устраивали, то я снова бы столкнулся с предыдущей ошибкой).

Однако, эти поиски привели меня к проекту nxhack/openwrt-node-packages, бинарники которого можно было собрать самостоятельно, что я и сделал. Делюсь инструкцией по сборке (как и получившимися ipk файлами) со всеми желающими.

Для начала, необходимо уточнить, что просто скомпилировать Node.js и установить его на официальную версию OpenWrt не выйдет - при запуске вы получите пресловутую ошибку "Illegal instruction". Необходимо будет заново полностью пересобрать прошивку с включенной опцией MIPS FPU Emulator и залить ее на роутер.

Все действия производились на Ubuntu 18.04 с установленными крайними обновлениями на момент выхода статьи. В качестве целевой системы была выбрана OpenWrt 19.07.4 (так же последняя, доступная на то время).

1. Устанавливаем необходимые зависимости:

sudo apt-get update
sudo apt-get install subversion g++ zlib1g-dev build-essential git python python3 python3-distutils libncurses5-dev gawk gettext unzip file libssl-dev wget libelf-dev ecj fastjar java-propose-classpat make gcc-multilib g++-multilib nano

2. Скачиваем исходники OpenWrt из необходимой нам ветки:

git clone git://github.com/openwrt/openwrt.git -b v19.07.4 && cd ./openwrt

3. Открываем файл со списком источников:

nano ./feeds.conf.default

И добавляем в него следующую строчку:

src-git node https://github.com/nxhack/openwrt-node-packages.git

4. Обновляем источники и устанавливаем пакеты из них:

./scripts/feeds update -a
./scripts/feeds install -a

5. Выполняем тоже самое, но отдельно для Node.js:

./scripts/feeds update node
rm ./package/feeds/packages/node
rm ./package/feeds/packages/node-*
./scripts/feeds install -a -p node

6. Скачиваем конфигурационный файл официальной сборки:

wget -O ./.config https://downloads.openwrt.org/releases/19.07.4/targets/ramips/mt7621/config.buildinfo

7. Запускаем утилиту конфигурирования:

make menuconfig

Изменяем профиль устройства:

  • Target Profile
    Xiaomi Mi Router 3G

Включаем поддержку MIPS FPU Emulator в ядре:

  • Global build settings > Kernel build options
    [*] Compile the kernel with MIPS FPU Emulator

Добавляем в нашу сборку Node.js в виде внешних пакетов:

  • Languages > Node.js
    -M- node
  • Languages > Node.js > node > Configuration ---> Version Selection
    10.x Maintenance LTS / 12.x Active LTS
  • Languages > Node.js
    <M> node-npm

Сохраняем изменения и выходим

8. Исправляем vermagiс ядра

Чтобы в будущем не возникло проблем с установкой дополнительных модулей для ядра, необходимо немного подправить скрипты сборки:

nano ./include/kernel-defaults.mk

Находим в нем следующую строчку:

grep '=[ym]' $(LINUX_DIR)/.config.set | LC_ALL=C sort | mkhash md5 > $(LINUX_DIR)/.vermagic

И заменяем ее на:

grep '=[ym]' $(LINUX_DIR)/.config.set | LC_ALL=C sort | echo 2e88863ccdd594fb8e842df3c25842ee > $(LINUX_DIR)/.vermagic

9. Запускаем компиляцию:

make download
make -j5

Где в -j5 указываем число ядер процессора + 1 (в примере показано для 4-ядерного процессора).

10. Ждем окончания (обычно полчаса-час, в зависимости от параметров компьютера).

При успешном завершении, необходимые нам ipk пакеты будут лежать в каталоге ~/openwrt/bin/packages/mipsel_24kc/node/

Образ же самой прошивки в ~/openwrt/bin/targets/ramips/mt7621/

11. Если же, по какой-либо причине процесс прервется ошибкой, то необходимо будет выполнить очистку:

make clean

И запустить компилирование заново, используя только одно ядро и включив вывод подробной информации (это займет больше времени):

make -j1 V=99

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


UPD1. Вы можете скачать уже готовый файл конфигурации, что позволит пропустить пункты 6 и 7 данной инструкции:

wget -O ./.config https://io-net.ru/wp-content/uploads/2020/09/mir3g_node.config

UPD2. При установке дополнительных модулей ядра на собственноручно собранную прошивку вы можете получить следующую ошибку:

* satisfy_dependencies_for: Cannot satisfy the following dependencies for <package_name>:
*      kernel (= 4.14.195-1-2e88863ccdd594fb8e842df3c25842ee)
* opkg_install_cmd: Cannot install package <package_name>.

Для ее исправления в уже собранной и установленной прошивке откройте файл /usr/lib/opkg/status

opkg update
opkg install nano
nano /usr/lib/opkg/status

Найдите в нем информацию об установленном ядре:

Package: kernel
Version: 4.14.195-1-022f8f3dd46d06d2163c38cafcd0d555
Depends: libc
Status: install user installed
Architecture: mipsel_24kc
Installed-Time: 1599409179
Auto-Installed: yes

И замените строчку "Version: ..." на следующую:

Version: 4.14.195-1-2e88863ccdd594fb8e842df3c25842ee

UPD3. Так как при сборке мы использовали внешний источник (nxhack/openwrt-node-packages), то обновление списка пакетов (opkg update) будет сопровождаться следующей ошибкой:

Collected errors:
 * opkg_download: Failed to download http://downloads.openwrt.org/releases/19.07.4/packages/mipsel_24kc/node/Packages.gz, wget returned 8.

Не стоит волноваться, на работоспособность это никак не влияет и данное сообщение можно просто игнорировать.


Скачать OpenWrt (sysupgrade) с поддержкой MIPS FPU Emulator:

Скачать Node.js (v10.22.1):

Скачать Node.js (v12.18.4):

Обсуждение

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *