Skip to content
 

Нативный тулчейн для OpenWRT

Как убить три недели (зачеркнуто) пол-года

Или Собираем нативный тулчейн для OpenWRT,  а заодно развлекаемся с новой игрушкой. Лирическое вступление. Вот и настало время, когда старого верного Асус-wl500gpv1 стало не хватать. Ибо и на ноутах уже на всех WiFi класса N давно, и карты гигабодные, и интернет шустрый, и стало заметно - ограничивает старичок полосу по всем направлениям.

На что менять - вопросов даже не возникло, любимый всеми TP-Link wr1043ND был куплен в ближайшей лавке, и разложен для препарирования: надо ведь еще родную прошивку заменить на что-то более приличное. В асусе почти с самого начала жила прошивка "от энтузиастов", наследница прошивки "от Олега", ведущая свой род от NSLU2 и поэтому совместимая со всем богатством Optware. С подключенной роутер с подключенной консольювнешней флешкой роутер чувствовал себя почти полноценным компьютером: прямо на нем можно было собирать и запускать практически весь линуксовый софт. И даже этот сайт одно время жил именно на этом роутере :)

Вот только прошивка эта - чисто броадкомовская, а новый роутер сделан на совершенно другом железе. После недолгих поисков совместимых сборок выбор остановился на OpenWrt - с тех времен, когда я выбирал прошивка для Асуса, она заметно похорошела, и даже отрастила приличный веб-интерфейс. Ну, поехали! скачиваю, прошиваю, перезагружаюсь... ЛЯПОТА! И интерфейс продуманнее чем у Асуса, а насколько удобнее работа с конфигурацией! JFFS2 с оверлеем это почти чудо, не нужно теперь лазить по /tmp/sbin/etc, больше никаких flashfs save && flashfs commit, все работает совершенно прозрачно - просто берешь, редактируешь и сохраняешь. Как на нормальном компе! Красотень :)

Подключаю внешнюю флешку, монтирую оверлеем - на роутере теперь 16гб места! Эх, раззудись, плечо! Сейчас мы туда пакетиков разных нужных наставим... так, mysql, php, lighttpd... ну и до кучи build_essentials. Стоп, как это "пакет не найден"? Почему? Лезу в список пакетов - и точно, никих инструментов - и главное нету GCC. Вот так вот.

Но ведь есть инструкция по кросс-сборке пакетов! И кто мешает собрать все необходимое? С такими мыслями изучаю инструкцию по самостоятельной сборке OpenWRT, скачиваю дерево исходников стабильной ветки, и в точности по инструкции делаю feeds update -a && feeds install -a.

Когда по экрану поползли бесконечной чередой строки, я понял что что-то тут не так, и заглянул в скрипт feeds (благо весь инструментарий сборки - это скрипты и мейк-файлы!). Ну да, мантейнерам именно эту команду и надо вводить, я совершенно согласен - но мне-то зачем ВСЕ пакеты?! Стираю дерево исходников "под самый корешок", закачиваю снова, но пакеты уже ставлю выборочно. Ввожу make - и через секунду наблюдаю первую ошибку сборки. Это под конец данной "опупеи"  я к ним привыкну, а пока смотрится диковато - таки ж релиз!  - и не собирается... Ошибка оказывается известной и легкоустранимой.  Вместо простого "make" делается скрипт обертки, который добавляет недостающие пути, а после второй ошибки - и недостающие переменные среды, и отныне запускаем сборку им.

Ну значит запускаю... и через несколько минут наблюдаю уже третью ошибку, но на этот раз исправить ее не так легко. Да, релиз собирался... когда-то, и в интернете были именно те самые версии нужных пакетов. Но с момента выпуска релиза прошло почти три года, и далеко не всегда можно найти те древние версии... Потыркавшись немного, решаюсь-таки собирать текущую версию, тем более ежели верить отзывам в интернете то собирается она легко.  Сохраняю конфигурацию, стираю старые исходники и загружаю новые. Запускаю сборку... правильно, опять ошибка: не найден broadcom-wl-5.100.138.tar.bz2. Покопавшись в сборочных скриптах, с удивлением обнаруживаю - это какой-то броадкомовский драйвер при сборке оттуда выделяют. Зачем на Атеросе броадкомовский драйвер - загадка, но быстрее скачать нужный файл чем эту загадку разгадывать. С этого места до окончания сборки не было ничего интересного - вылазили какие-то мелкие ошибки, которые легко устранялись, так что к концу первой недели прошивка таки собралась.

Но это ведь только начало - основная задача это инструментарий! Заглядываю в дерево исходников, и с удивлением вижу - вот же GCC! есть, и все вокруг уже готовое - но вот не показывается при выборе конфигурации. Ааа, это потому что разрешена его сборка только для платформы x86 - а остальным ни к чему, да? Редактирую мейк-файл, запускаю - и тут начинается самое интересное. Потому что GCC хочет кучу библиотек на целевой машине, из которых в готовая есть только одна. По образцу делаю остальным мейк-файлы, прописываю зависимости,  создаю по инструкции custom feed, feeds update - ошибка. Оно оказывается может быть только в жестко заданном месте - /usr/openwrt/custom-feed. Выручает симлинк... Запускаю сборку...

Надо тут отметить, что правильнее говорить "запускаю сборку и иду заниматься чем-либо другим", потому что на данном этапе требуется минут 5, чтобы добраться через весь сценарий сборки до непосредственно сборки моего пакета. И это - на верхнем i5! Ну вот, запускаю сборку, но собираться эти пакеты не хотят - ошибки странные, разные и совершенно непонятные. Таак, а как другие пакеты собираются? Что это тут за параметр такой интересный - PKG_FIXUP? А какие они вообще бывают? Пробуя их сначала по очедери, а потом в разном наборе, через десяток-другой попыток сборки пакеты наконец-то собираются!

Теперь - снова GCC. Указываю ему на собранные библиотеки, запускаю сборку... правильно, ошибка. Не могу, говорит, найти ту библиотеку из свежесобраных. Одна есть - а другой нет. Мистика! Начинаю разбираться - оказывается, собралась только статическая версия. Стираю флаг собранности и запускаю сборку заново, потом смотрю лог. Ага! "линкер не поддерживает разделяемые библиотеки" - вот это да! у всех остальных пакетов поддерживает, а у этого нет? Разбирался с этим долго...

Оказалось - ошибка в самом файле configure: в начале него определяется в том числе и расположение утилиты grep, записывается в переменую - а после используется  эта утилита для обнаружения некоторых возможностей. Так вот, при  кросскомпиляции в нем пропускается значительная часть, в которую попадает и это определение - так что обращение идет к пустой переменной...  Но долго было выяснять - быстро исправить, EGREP=/bin/grep в строку вызова, и все дела. Снова подход к GCC, снова ошибки, ошибки... то библиотек не хватает, то заголовочных файлов, то он забывает во вторую стадию их перетащить... Постепенно набирается тот набор ключей конфигурирования,  когда GCC перестает ругаться, и вроде как начинает собираться.

Ну да, начинает: собирается до середины, и при переходе на 2 стадию вдруг выпадает с ошибкой - не найден fenv.h  Как он может быть не найден - вот их  на любой вкус! И тут, и тут... Интересно, а где он его ищет? Опс - оказывается при этом он вызывается вообще как-то хитро, без передачи ему половины ключей! Гуглю, много. И где-то на задворках находится багтрекер самого GCC, где эта самая ошибка помечена как решенная бага!!! Но хотя она там и "решенная", но в обсуждении находится временная "затычка" в виде секретного ключа для configure. Добавляю, собираю... Через пару часов и еще несколько мелких ошибок сборки прошивка наконец-то собирается!

После всего пережитого даже как-то боязно ставить эту прошивку... но это лишь секундная слабость :) Прошиваю, перегружаю - вуаля! Веб-интерфейс роутера с волнующей надписью "OpenWrt Bleeding Edge r35671"! Только вот флешка не смонтировалась... Значит забыл что-то включить в прошивку. Снова make menuconfig, ставлю недостающие галочки, ну и заодно прохожу по всей конфигурации в поиске - а нет ли чего лишнего. Убираю самбу, добавляю некоторые библиотеки, и чуть меняю настройки busybox'a.

Собираю прошиваю.... а че так долго? А где веб-интерфейс? А почему роутер уже не пингуется??? Постепенно начинает доходить - здравствуй, кирпич. Но без паники - прежде чем заниматься перепрошивкой, я убедился в наличии способов восстановления, и самый простой из них - консоль на последовательном интерфейсе.

Под нож идет старый дата-кабель от Ерикссона 320, содержащий в себе нужную микросхему преобразователя USB - serial, роутер аккуратно разбирается... черт бы побрал такую экономию! Разъем консоли на плате отсутствует. Надо паять...  ну, прощай, гарантия! Процесс восстановления прошивки через консоль оказался простым и легким. Сразу стало видно почему прошивка не загрузилась, соответственно сделана исправленная версия. Необходимые приготовления, 4 простые команды по шпаргалке - и новая прошивка радостно загружается. На этот раз все смонтировалось как надо, да и версия успела обновиться до 35690 :)  С момента покупки роутера прошло три недели и один день...

Теперь очередь тестирования: настроенный роутер укладывается в стол, и пытается подключиться к провайдеру. Только вот внешний кабель отсутствует :) - и значит тыркаться ему предстоит весьма долго. Он железный, пусть трудится. Смотрю через пару часов - опс, а почему лампочки погасли? И роутер уже не пингуется...  Перегружаю - все ОК. Что ж, запускаю тест снова, но при этом открываю консоль и в ней запускаю "top" - теперь при зависании будет видно чем все кончилось.  Через некоторое время вижу, что роутер постепенно начинает тормозить, а процессы ksoftirqd пожрали весь процессор. Ну здравствуй, бага...

Баг оказался злобным и странным: независимо от количества памяти, свопа, запущенных процессов етц цикл попыток установления соединения PPTP гарантированно приводил к зависанию. В багтрекере OpenWrt этот баг провисел пол-года, и... случайно прошел сам при очередном обновлении ядра до версии 3.10. Остается пара финальных штрихов, и новый роутер отправляется на свое постоянное место - висеть на стенке. И года не прошо :)

Немного статистики: общий объем загруженных файлов составил 902мб, размер целевой системы - 12гб. Из всего этого получилась прошивка размером 6мб и 96мб пакетов. PS. Каждый раз, собирая что-то для МИПСов, меня удивляет одна маленькая деталь. Общепринятое мнение: x86 это CISC, сложные команды и компактный код, в то время как архитектура MIPS это RISC - простые команды, но много. В связи с этим вопрос - а почему вдруг размер всех утилит после компиляции для МИПСа получается меньше? Например iptraf в собранном виде для x86 имеет размер 189кб, тогда как собранный для MIPS  с теми же параметрами конфигурирования - только 153кб?

Также можно почитать:

  1. Переделка маслосистемы (6.7)
  2. Вовремя регулируйте клапана! (5.9)
  3. Новые магнитные пробки в действии. (4.3)

Написать отзыв