Некоторое время назад мне предложили немного поработать с одноплатным ПК Orange Pi 2G-IOT (встроенный 2G и цена выглядят очень привлекательно). Прочитав пост об апельсиновом рае, я подумал, что без затруднений повторю этот путь, тем более, что с Linux я на «ты» (вернее, так я думал недели три назад) и уже имел опыт общения с Raspberry Pi 2 B+. На практике этот путь оказался намного длиннее. Создавалось ощущение, что наши китайские друзья намеренно создавали сложности (причём иногда с особым цинизмом). Если вы захотели сэкономить и купить эту плату, то сначала прочитайте этот пост и подумайте ещё раз.

По возможности, я постараюсь сдерживать эмоции или как минимум переводить их в юмор.
Итак, вот мне в руки попадает плата и SD карточка десятого класса. Поехали.

Всё ниже написанное относится к модели Orange Pi 2G-IOT, но в чате Телеграма (ищите «Orange Pi и не только») говорят, что модели 2G, 3G и 4G примерно одинаково себя ведут (одинаково плохо). Написанное НЕ относится к, например, Orange Pi PC и Orange Pi One, которые по отзывам ведут себя стабильно.

Мина №1 (учебная): скачивание образа ОС


Казалось бы, что может быт�� проще? Идём на сайт производителя и качаем. Однако все ссылки ведут на mega.nz, который собирает его прямо в браузере. Мой дешёвый ноутбук с 4 Гб ОЗУ не потянул такую задачу и вкладка упала. Можно было бы воспользоваться фирменной программой для скачивания с Меги, но он у меня не вызвал доверия (тем более, что в Интернетах некоторые пишут, что программа распознаётся антивирусами как вредоносное ПО). Варианты решения: скачать с неофициального сайта (например, здесь), развернуть виртуалку и поставить в ней клиент для скачивания с Меги, попросить кого-то с более современным ПК скачать образ.

Ещё немного об операционках для апельсина
Для многих моделей Апельсинок пользователи рекомендуют Armbian, но на 2G-IOT он на меня впечатление не произвёл: выглядит как минималистичный Raspbian. Кстати, на сайте Армбиана образа для 2G-IOT нет, только на сайте Orange Pi. Также пробовал Ubuntu Server, но он у меня вообще не подавал признаков жизни. Встроенный в NAND Андроид по всей видимости рабочий, но я его никак не изучал, скорее всего, без сенсорного экрана он малополезен. Кстати, напоминаю, что устройство загрузки определяется положением перемычки в уголке платы, по умолчанию стоит загрузка со встроенной NAND памяти.

Мина №2: выход в Интернет через модем


Дословно следуя настройке wvdial и pppd в Интернете, я внезапно обнаружил, что ping запросы проходят исправно, а вот обычные TCP пакеты ни в какую:

orangepi@OrangePi:~$ curl --interface ppp0 195.201.201.32
curl: (7) Failed to connect to 195.201.201.32 port 80: Connection timed out
orangepi@OrangePi:~$ curl --interface ppp0 195.201.201.32
curl: (7) Failed to connect to 195.201.201.32 port 80: Connection timed out
orangepi@OrangePi:~$ curl --interface ppp0 195.201.201.32
curl: (7) Failed to connect to 195.201.201.32 port 80: Connection timed out
orangepi@OrangePi:~$ curl --interface wlan0 195.201.201.32
46.0.208.54
orangepi@OrangePi:~$ ping 195.201.201.32 -I ppp0
PING 195.201.201.32 (195.201.201.32) from 10.33.64.21 ppp0: 56(84) bytes of data.
64 bytes from 195.201.201.32: icmp_seq=1 ttl=52 time=664 ms
64 bytes from 195.201.201.32: icmp_seq=2 ttl=52 time=240 ms
64 bytes from 195.201.201.32: icmp_seq=3 ttl=52 time=234 ms
64 bytes from 195.201.201.32: icmp_seq=4 ttl=52 time=246 ms
64 bytes from 195.201.201.32: icmp_seq=5 ttl=52 time=241 ms
64 bytes from 195.201.201.32: icmp_seq=6 ttl=52 time=237 ms
^C
--- 195.201.201.32 ping statistics ---
7 packets transmitted, 6 received, 14% packet loss, time 6032ms
rtt min/avg/max/mdev = 234.634/310.971/664.998/158.370 ms
orangepi@OrangePi:~$

Решение подсказал edtun: https://www.linux.org.ru/forum/admin/12135523, хотя допускаю, что можно было как-то проще.

Сразу насторожило, что IMEI модема забит нулями. Благо, красно-белый оператор связи не обращает на это внимание. (Кстати, у встроенного WiFi аналогично нет МАС-адреса: при каждом передёргивании питания он генерируется случайным образом.)

Мина №3: USB порт


Втыкаем WiFi свисток в USB разъём и… Ничего не происходит. lsusb отобразил пустой USB порт. Небольшое копание показало, что в плате реально всего один USB. И по умолчанию он подключен к microUSB порту. Для переключения его на обычный USB HOST необходимо переключить на плате джамперы, которые находятся рядом с перемычкой для выбора загрузки. Их описание есть на 4pda:
Решение: переключить джамперы в положение: 1234 вниз, 5678 вверх.

Только потом я нашёл небольшое упоминание об этом нюансе в мануале к Orange Pi.

Мина №4: Драйверы


Теперь устройство определяется в системе, lsusb отображает производителя и код продукта, но беспроводной сетевой интерфейс в системе не определяется. Потому что разработчики не завезли на апельсинку драйвера для WiFi адаптеров. Причём вообще никаких. Есть драйвер только для встроенного WiFi, не больше и не меньше. А что мы делаем, когда у нас нет драйвера под наше железо? Правильно, идём собирать их из исходного кода!

Мина №5: Подготовка к сборке


В переписке bad__day предложил сборку непосредственно на Orange Pi. Может быть, это возможно, но мне не удалось.

Для Orange Pi разработчики сделали специальную Orange Pi Build System, с помощью которой в теории для сборки ядра или модулей к нему достаточно просто следовать указаниям на экране. Подробная инструкция изложена в мануале начиная с 61-й страницы. Казалось бы, просто следуй, и всё будет хорошо, но нет.

Во-первых, чтобы вручную не править все зависимости на своём компьютере (я регулярно обновляю ПО, это здорово, но не в этот раз), я развернул виртуалку с Ubuntu 16.04 и все действия проводил там. Во-вторых, в скриптах где-то вкралась ошибка, и Build System не ставила тулчейн для кроссплатформенной компиляции. Решается это таким костылём:

  1. Вручную apt-get'ом ставим тулчейн для кросскомпиляции под ARM.
  2. Делаем симлинки:
    mkdir $HOME/OrangePiRDA/toolchain/bin
    ln -s $(which arm-linux-gnueabi-ld) $HOME/OrangePiRDA/toolchain/bin/arm-linux-gnueabi-ld
    ln -s $(which arm-linux-gnueabi-gcc-4.9) $HOME/OrangePiRDA/toolchain/bin/arm-linux-gnueabi-gcc
    ln -s $(which arm-linux-gnueabi-g++-4.9) $HOME/OrangePiRDA/toolchain/bin/arm-linux-gnueabi-g++
    ln -s $(which arm-linux-gnueabi-ar) $HOME/OrangePiRDA/toolchain/bin/arm-linux-gnueabi-ar
    ln -s $(which arm-linux-gnueabi-nm) $HOME/OrangePiRDA/toolchain/bin/arm-linux-gnueabi-nm
    ln -s $(which arm-linux-gnueabi-objcopy) $HOME/OrangePiRDA/toolchain/bin/arm-linux-gnueabi-objcopy
    ln -s $(which arm-linux-gnueabi-size) $HOME/OrangePiRDA/toolchain/bin/arm-linux-gnueabi-size
    Обратите внимание: компилятор берётся версии 4.9, на версиях выше ничего не соберётся.
  3. Открываем OrangePiRDA/scripts/Prepare_toolchain.sh и на всякий случай комментируем строки, упоминающие тулчейн.

На самом деле все эти скрипты просто вызывают apt-get install -y… и make. Скрипт не предлагает пользователю как-либо изменять конфигурацию (или я не нашёл?).

Но ведь нам ничего не мешает самим вызвать

make menuconfig

и отметить нужные драйверы. Делаем это и снова собираем (теперь можно только модули) и…

Мина №6 (с прикрученным ИК датчиком движения и запасным детонатором): Сборка драйвера


… И тут скрипт приветливо стал задавать вопросы, как ему конфигурировать ядро. Он вызвал старомодный конфигуратор ядра, но почему?! Что не так?

Оказалось, что в Makefile прописано проверять ВРЕМЯ(!!!) изменения конфига!



В комментарии дословно написано «кто-то копался». (На скриншоте уже изменённый Makefile, я прописал menuconfig.) Пробовал вызывать make oldconfig, не заметил, чтобы это что-то где-то изменило. Ладно, теперь ведь при сборке вызовется menuconfig, это не страшно. Снова вызываю сборку, сборка замечает, что «кто-то копался в конфиге», вызывает menuconfig, я выхожу и жду завершения. А теперь представьте моё удивление, когда я не нашёл выбранный мною драйвер.

Дисклеймер перед дальнейшим прочтением
На этом месте меня покинуло понимание происходящего, а также я окончательно потерял связь с реальностью, здравым смыслом и цивилизацией с планеты Ross 128 b. Я вышел за границы знаний своих, всех моих знакомых и TARDIS. Я начал творить полный бред, а единственной целью стало собрать этот [CENSORED] драйвер любой ценой. Если при прочтении текста выше Вы хватались за голову более двух раз, то текст ниже не читайте. Так будет спокойнее и вам, и мне. Если вы можете дать внятное объяснение происходящему и объяснить, где я не прав и как надо, то прошу рассказать. Пожалуйста.



Что ж, лезем разбираться. Оказывается, make создаёт файл modules.order, где описаны все модули, которые будут скомпилированы. И даже после всех изменений конфига и его сохранения этот файл заполняется одинаковым набором. Я не придумал ничего лучшего, чем вручную дописать в него строки (мой свисток собран на чипсете RTL8192CU):

kernel/driver/net/wireless/rtlwifi.ko
kernel/driver/net/wireless/rtlwifi/rtl8192cu.ko

Все упоминания этого файла в Makefile заменил на modules.order.fake. Запускаю сборку. На этот раз сборка пошла, но оборвалась, так как аналогичного файла нет в папке с исходным кодом rtlwifi. Я переименовал в этой папке и подпапках файлы modules.order.fake на modules.order, и это стало моим последним приключением при сборке драйвера. После этого система ещё два раза выводила мне menuconfig, как будто спрашивая меня «ты точно этого хочешь?», но всё же собрала дополни��ельно три заветных .ko файла, которые завелись как положено.

Мина №7: Совместная работа внешнего WiFi и модема


Немного поигравшись с airodump'ом и убедившись, что как минимум ловить пакеты в режиме монитора устройство умеет, я решил проверить модем ещё раз. Выполняю

sudo wvdial

И светодиод на внешнем WiFi адаптере гаснет, а SSH отваливается. В логах потом прочитал, что адаптер был отключен. Первая мысль — проблема с питанием. До этого момента я использовал свой зарядник на 1,5 Ампера, а производитель рекомендует аж целых 3 (куда столько? Она и одного Ампера даже не ест). Под рукой был зарядник на 2 Ампера, который годами исправно питал Raspberry Pi.

На данный момент я не нашёл какого-либо стабильного решения данной проблемы. Вот некоторые попытки решения:

  • С вероятностью 80% можно отключить внешний WiFi с помощью:

    chmod 777 /sys/bus/usb/drivers/usb/unbind
    echo 1-1 > /sys/bus/usb/drivers/usb/unbind

    а затем запустить wvdial, который с 1-3 попытки установит соединение и можно выйти в Интернет. В 20% разного рода зависания и глюки.
  • Однажды случайно оказалась такая ситуация, что был убит wvdial, но pppd остался работать (как так может быть?), после которого поднялся внешний WiFi (см. выше, только вместо unbind пишем bind) и связь через модем была. Воспроизвести ситуацию не удалось.
  • Оказалось, что можно без пересборки ядра отключать питание на USB с помощью такой утилиты командой

    ./hub-ctrl -h 0 -P 1 -p 0

    и включить питание
    ./hub-ctrl -h 0 -P 1 -p 1
    На 2G-IOT поведение непредсказуемое: отключение питания может быть либо на одну секунду, либо до перезагрузки. При некоторых фазах Луны попытка вернуть питание приводит к зависанию платы.
  • Переключить джамперы на OTG (1234 вверх, 5678 вниз), питание подать на ноги GPIO 2 и 6 (прозванивал, они напрямую соединены с питанием microUSB)

    Распиновка


    подключить WiFi адаптер через USB-OTG переходник от смартфона. Система не видит USB устройства вообще. Возможно, надо настойчивее поиграться с джамперами.

Не проверялось, но может сработать (в планах опробовать все эти варианты):

  • Другой WiFi адаптер.
  • Очень стабильный источник питания с максимальным током 3 Ампера.
  • Дополнительное питание к ногам USB.
  • Бензин и спички.

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

На этом пока всё.

Благодарности
Хотелось бы выразить свою благодарность bad__day, edtun, А. Репину, форумчанам с 4pda, старожилам в чате Телеграма и Коту, который терпеливо выслушивал меня всё это время и почти не пытался сбежать.


UPD: Сегодня мне привезли источник питания с выходом 5В 3А. С ним удалось одновременно запустить и модем, и USB WiFi адаптер. Модем сыплет ошибками, перестаёт отвечать, но в среднем с третьей попытки подключается. После этого можно использовать USB WiFi.

Подводя итог.


Одноплатник Orange Pi 2G-IOT очень сырой и почти не поддерживается производителем. Даже на простых вещах, где казалось бы ничего не предвещает беды, что-то может пойти не так. Если необходимо использовать устройство с выходом в Интернет через мобильную сеть и вы не уверены, что сможете совладать с Orange Pi, то лучше доплатить и взять что-то более надёжное и отлаженное. Сбережёте время и нервы.