Хабрахабр

[recovery mode] Orange Pi 2G-IOT: карта минного поля

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

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

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

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

Ещё немного об операционках для апельсина

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

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

04 и все действия проводил там. Во-первых, чтобы вручную не править все зависимости на своём компьютере (я регулярно обновляю ПО, это здорово, но не в этот раз), я развернул виртуалку с Ubuntu 16. Решается это таким костылём: Во-вторых, в скриптах где-то вкралась ошибка, и 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.
  • Бензин и спички.

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

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

Благодарности

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

Теги
Показать больше

Похожие статьи

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

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

Кнопка «Наверх»
Закрыть