DIY-роутер GL-MT300N-V2. Часть 1 - знакомство и сборка кастомной прошивки для переопределения функции GPIO-порта

Есть такой замечательный DIY-роутер GL-MT300N-V2 от GL-iNet. Он интересен тем, что позволяет радиолюбителю получить доступ к портам ввода-вывода GPIO (они выведены на плату) и совместим с роутерной ОС OpenWRT. Плюс, имеет всего один LAN-порт. Смекаете? Да, его можно и нужно использовать для удалённого управления периферией по Ethernet и создания VPN-туннелей. Подключаетесь к роутеру через виртуальную частную сеть и удалённо дёргаете ножками GPIO, например, переключая какое-нибудь реле. Очень удобно. Что ж, попробуем применить его для такой задачи. Пусть имеется компьютер, на котором хранятся какие-нибудь нужные файлы. Требуется обеспечить безопасный доступ к этому компьютеру из любой точки мира. Ну, здесь всё просто: включаем наш роутер в разрыв сетевого соединения компьютера (Ethernet-кабель провайдера вместо компьютера подключаем к WAN-порту роутера, а сам компьютер подсоединяем к единственному LAN-порту). И настраиваем на роутере VPN-сервер. Таким образом, подключившись из любой точки мира к нашему роутеру по VPN, мы попадаем в безопасную внутреннюю сеть, в которой доступен наш целевой компьютер. Но вот незадача: не будешь же держать компьютер вечно включённым? Нужно сделать так, чтобы компьютер включался по требованию. Удалённо. И здесь нам на помощь приходит главная отличительная особенность GL-MT300N-V2: возможность доступа к портам ввода-вывода. Войдя в виртуальную локальную сеть и удалённо управляя ножками GPIO, мы можем подать целевому компьютеру сигнал на включение и выключение. Попробуем реализовать этот проект.

Сначала сделаем "в лоб" - просто заменим стоковую прошивку роутера на OpenWRT. Это просто до невозможности: заходите на страницу GL-MT300N-V2 на сайте OpenWRT, скачиваете оттуда прошивку, а потом устанавливаете её на роутер через штатный механизм обновления прошивки.

Пошаговый алгоритм:
1. Подключите LAN-порт роутера к сетевой карте компьютера напрямую при помощи патч-корда.
2. Подайте питание на роутер.
3. Откройте Ваш любимый браузер и введите адрес 192.168.8.1 (сетевой адаптер компьютера должен быть настроен на использование DHCP). Вы попадёте в панель управления роутером.
4. Найдите в меню пункт Firmware (в старых версиях стоковой прошивки) или Upgrade, и далее Local Upgrade.
5. Перетащите на поле заранее скачанный файл прошивки с OpenWRT.
6. Обязательно снимите галочку с пункта Keep settings!
7. Нажмите на кнопку Install. Начнётся процесс обновления прошивки.

Но окончания прогресса обновления Вы так и не дождётесь, потому что после прошивки у роутера изменится IP-адрес. Поэтому, просто закройте браузер, отключите сетевой адаптер компьютера (но не отключайте роутер от питания!), подождите несколько минут. Затем включите сетевой адаптер снова (это нужно, чтобы истекла аренда на предыдущий IP-адрес и компьютер мог подключиться к роутеру по новому адресу) и наберите в браузере адрес 192.168.1.1. Откроется админ-панель OpenWRT. Мануалов по настройке и использованию OpenWRT в Сети множество, здесь я подробно останавливаться не буду. Наша главная же цель была - научиться управлять GPIO по Ethernet, вот сразу этим и займёмся.

На плату у этого роутера порт GPIO, конечно, выведен. Распиновку можно посмотреть здесь. Но штырьки на плате распаяны только для GND, GPIO13 и GPIO12. Чтобы пока что плату не перепаивать, попробуем воспользоваться именно этими пинами. Они - ни что иное, как штыревые разъёмы PLS. Ответная часть к ним - разъём BLS. Очень удобно: можно обжать разъёмом BLS-2 сигнальный провод управляемой периферии и напрямую подключить её к распаянным на заводе штырькам. Так и сделаем, подключив к разъёму светодиод. Катод светодиода нужно подсоединить к выводу GND, а анод через резистор номиналом 1 кОм — к выводу GPIO13.

Подключаемся к роутеру по ssh и вводим следующие команды (наш пин GPIO13 имеет номер 13).

# echo 13 > /sys/class/gpio/export
# echo out > /sys/class/gpio/gpio13/direction
# echo 1 > /sys/class/gpio/gpio13/value
# echo 0 > /sys/class/gpio/gpio13/value

Это обычные команды Linux для управления портами GPIO. Но нас ждёт разочарование: они не работают. Почему? А потому, что распаянные пины заняты другой задачей - они установлены не как GPIO, а как UART. Если мы хотим в дальнейшем использовать их именно как порты ввода-вывода, то их поведение нужно переопределить. А для этого - собрать свой собственный вариант прошивки OpenWRT. Этим и займёмся.

Есть такой инструмент - OpenWRT Buildroot. Для начала, установим его. В первую очередь, нам понадобится Ubuntu. У меня она крутится в VirtualBox (действия, описанные в статье, проводились в Ubuntu Desktop 18.04 LTS). Если у Вас тоже, то не забудьте подключить "Образ диска дополнений гостевой ОС" и инсталлировать его содержимое. Запускаем Ubuntu, открываем терминал и пишем следующие команды.

Устанавливаем необходимые пакеты


$ sudo apt-get install build-essential libncurses5-dev git gawk python

Клонируем репозиторий OpenWRT


$ git clone https://github.com/openwrt/openwrt.git

Переходим в рабочий каталог


$ cd openwrt

Теперь нужно переопределить поведение нашего порта ввода-вывода. Откройте файл target/linux/ramips/dts/GL-MT300N-V2.dts (здесь и далее все пути приведены относительно директории openwrt) и в секции &pinctrl, в разделе "ralink,group" добавьте через запятую "uart0", вот так:

&pinctrl {
state_default: pinctrl0 {
gpio {
ralink,group = "wdt", "gpio", "wled_an", "p0led_an", "p1led_an", "i2s", "uart0";
ralink,function = "gpio";
};
};
};

Далее, выполняем команды:

$ ./scripts/feeds update -a
$ ./scripts/feeds install -a -p luci
$ make defconfig
$ make prereq

Если появятся ошибки, что не хватает какого-то пакета, доставьте его. Если же будут не ошибки, а предупреждения наподобие этих:

WARNING: Makefile 'package/utils/busybox/Makefile' has a dependency on 'libpam', which does not exist
WARNING: Makefile 'package/utils/busybox/Makefile' has a build dependency on 'libpam', which does not exist
WARNING: Makefile 'package/network/utils/curl/Makefile' has a dependency on 'libgnutls', which does not exist
WARNING: Makefile 'package/network/utils/curl/Makefile' has a dependency on 'libopenldap', which does not exist
WARNING: Makefile 'package/network/utils/curl/Makefile' has a dependency on 'libidn2', which does not exist
WARNING: Makefile 'package/network/utils/curl/Makefile' has a dependency on 'libssh2', which does not exist
WARNING: Makefile 'package/boot/kexec-tools/Makefile' has a dependency on 'liblzma', which does not exist
WARNING: Makefile 'package/network/services/lldpd/Makefile' has a dependency on 'libnetsnmp', which does not exist
WARNING: Makefile 'package/network/utils/nftables/Makefile' has a dependency on 'jansson', which does not exist

- просто игнорируйте их.

Теперь выполняем

$ make menuconfig

В появившейся утилите конфигурирования сборки выбираем:
Target System → MediaTek Ralink MIPS
Subtarget → MT76x8 based boards
Target profile → GL-iNet GL-MT300N-V2
LuCI → Collections → luci (если этого пункта нет, значит, команды ./scripts/feeds Вы не выполняли; LuCI - это веб-интерфейс для управления роутером)
LuCI → Modules → Translations → Russian
Можете что-нибудь ещё на свой вкус настроить. Например, мне потребовалось виртуальное устройство /dev/mem. Включается так: Global build settings → Kernel build options → /dev/mem virtual device support. Когда все настройки готовы - выбираете пункт Save, имя сохраняемого файла оставляете по-умолчанию ".config" и жмёте OK. Теперь можно начать собирать прошивку:

$ make -j2 V=sc

Часа через два собранную прошивку вы найдёте здесь: bin/targets/ramips/mt76x8/openwrt-ramips-mt76x8-gl-mt300n-v2-squashfs-sysupgrade.bin. Теперь её можно прошить в память роутера. Делается это, как обычно, через систему штатного обновления прошивки.

После перепрошивки снова подключаемся к роутеру по ssh и вводим уже знакомые команды:

# echo 13 > /sys/class/gpio/export
# echo out > /sys/class/gpio/gpio13/direction
# echo 1 > /sys/class/gpio/gpio13/value
# echo 0 > /sys/class/gpio/gpio13/value

Ура, заработало! Светодиод зажёгся, когда мы отправили на 13-й пин единичку, и погас, когда отправили ноль. Можно поздравить себя и переходить к следующему этапу. Вообще-то, и на этом этапе уже можно удалённо управлять портами ввода-вывода на плате роутера. Но, чтобы полностью автоматизировать этот процесс, лучше написать свою программу-демона на Си, чем мы в следующей части и займёмся.

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

Полезные ссылки:

1. Build system – Installation
2. OpenWrt Buildroot – Установка
3. OpenWrt Feeds
4. Сборка OpenWrt/LEDE из исходных кодов
5. Linux: кнопки, светодиоды и GPIO
2019-02-02