Приветствую профессиональное сообщество Хабра. В этой статье описана прошивка IPTV приставки MOTOROLA VIP1003 ARRIS, а также портирование приложения на архитектуру системы — SuperH SH с целью добавления функционала.

__

Питание 12В/1A. Композитный видеовыход. Существуют модели, имеющие разьём SCART вместо композитки. Форма корпуса диктуется, вероятно, вопросами совместимости с разьёмами SCART.
Внутренняя компоновка довольно просторная.

По центру расположен чип, в котором обьединены микропроцессор RISC архитектуры SuperH SH STx7105 и процессорное ядро архитектуры VLIW ST231. На базе ST231 реализован декодер видео H.264. Такая специфика по всей видимости и позволяет устройству работать с большим обьёмом видеоданных без перегрева.
Контактные площадки, которые расположены слева — это интерфейсы UART и EJTAG. Как видите, расположены они обособленно, так что подпаяться к ним можно не испортив другие компоненты. Обратим внимание на UART
UART
Оба крайних вывода — GND, средний вывод — питание 3В. Вывод ближе к задней стенке — TX. Интерфейс работает с уровнями TTL — 3В. Для подключения требуется преобразователь TTL/RS232 (или TTL/USB). О выводах RX мне известно лишь то, что он работает не у всех моделей.
Но нам и этого будет достаточно. Информация о ходе процесса перепрошивки выводится в последовательный интерфейс (UART). Параметры передачи: 115 200 бод 8N1 Информацию о любом сбое можно получить исключительно оттуда. Через видеовыход выводится лишь общее сообщение о неудавшейся загрузке ПО.
Настройки

Приставка обладает большим количеством настроек, доступных в меню. В подменю TV доступны настройки видеорежима PAL/NTSC.
Подменю сетевых настроек IP и дополнительных настроек Advanced открываются путём набора на пульте управления последовательности цифр 2357 и 7532 соответственно. В подменю IP настраивается метод получения адреса STATIC/DHCP и стандартные адреса шлюза, подсети, маска, а также разрешается или запрещается загрузка при неудачном получении сетевого адреса. В подменю Advanced настраивается порядок загрузки, адрес загрузки, адрес NFS сервера.
Приставка поддерживает несколько способов загрузки: Multicast, TFTP, HTTP и LS. Загрузка с NFS сервера не поддерживается, настройка предназначена для некоторых типов прошивок, которые используют NFS сервер вместо памяти устройства. Порядок загрузки задаётся настройками Kernel protocol и Splash protocol. Настройка Kernel protocol касается загрузки образа ядра, настройка Splash protocol — экранной заставки. Если в порядке загрузки указать 2 — приставка будет пытаться загрузить образ с TFTP сервера. Если в порядке загрузки указать 6 — приставка будет пытаться загрузить образ с HTTP сервера. Очень много настроек, касающихся загрузки с TFTP сервера. Приставка поддерживает загрузку с пула TFTP серверов 4 (четырёх) нод. Задаётся количество попыток загрузки с одной ноды и количество попыток подключения к пулу, таймаут а также размер блока. Адрес ноды может анонсироваться DHCP сервером и необходимость в указании адреса отпадает. Задать можно имена загружаемых файлов. Если адрес загружаемого файла анонсирует DHCP сервер и в настройках указан метод получения адреса от DHCP сервера, имя файла, указанное в настройках, не будет иметь силы.
Выполненные настройки не сохраняются автоматически. Я намеренно не описал ещё одно подменю. Ниже поймёте почему.
Прошивки и SDK
Желательно заранее загрузить и верифицировать программное обеспечение, необходимое для прошивки устройства. Ниже приведен список ссылок для загрузки.
kreatv‑kernel‑SMARTLABS.bin — загрузочное ядро.
rt firmvare ver. 5.24246.191016 (legacy) — прошивка (первичная) от Rostelecom.
PHP‑MOTO1003VIP — прошивка с php сервером и telnet. Перед прошивкой на приставке в ОБЯЗАТЕЛЬНОМ порядке должна стоять версия LEGACY 5.24246.191016 (ТОЛЬКО ОНА И НИКАКАЯ ИНАЧЕ).
toolchain_st40_2.5.0.tar.bz2 — утилиты для сборки собственных приложений
После загрузки проверьте хэши прошивок sha265. Эти прошивки проверить очень важно.
SHA265: 5fae869425b054a34975dd1f62ba99cc40f7e69c98af504301a5f15af7939f6c kreatv‑kernel‑SMARTLABS.bin
SHA265: b5976a0a6a4d023ab9318ff274fa5dec369b2a47014cad682bfe79249f777e8a firmware_vip19×3_5.24246.191016.bin
Опишем каждый компонент подробнее.
Ядро kreatv‑kernel‑SMARTLABS.bin загружается с FTP сервера. При последуюих запусках ядро ищет файл firmware.bin на флеш‑карте или на сетевом ресурсе. Дальнейшей загрузки не происходит. Если прошивка найдена, ядро начинает её запись в память. Если быть точным, то ядро запускает файл, чем бы он ни был. Ядро может запустить подписанный скрипт, и уже этот скрипт записывает прошивку. Содержимое скрипта не проверяется. Технически можно скопировать легитимный скрипт в корень флешки под именем firmware.bin и видоизменить его содержимое под произвольные нужды. Например, для удобства, запуск другого скрипта. Помимо подписи, скрипт должен содержать код для поиска и монтирования флешки Загрузочное ядро содержит утилиту wget, таким образом возможна даже загрузка скрипта из сети. Это можно использовать например для получения информации от утилит dmesg, uname, ps
Прошивка rt firmvare ver. 5.24246.191016 (legacy) содержит SSH сервер, однако доступ невозможно получить так как применяются ассиметричные ключи RSA. Состоит из одного файла firmware.bin. После перепрошивки файл переименуется в firmware_done.bin
Прошивка PHP‑MOTO1003VIP содержит PHP сервер и TELNET. PHP сервер предоставляет веб‑интерфейс, доступ к которому возможен по URL http://[IP]/index.php. Веб интерфейс предоставляет возможность загрузки плейлиста пункты которого затем станут доступны в приложении для их выбора с пульта. Приложение загружается и работает автономно, воспроизведение контента возможно из локальной сети. Логин: root/12341234. Сообщения, которые выводятся в UART, дублируются в файле /var/log/messages.
Состоит прошивка из четырёх файлов
branding.bin (CRC32: 0D A7 4F FB) — фирменное приложение
firmware.bin (CRC32: D8 12 47 D9) — подписанный скрипт
rootfs.bin (CRC32: 7B 74 4E 7F) — загружаемый образ системы
splashimage.bmp (CRC32: AB 3D C3 93) — экранная заставка
Toolchain для сборки приложений располагается внутри архива SDK: kreatv‑kit‑oss_4.2_st40.tgz, который можно загрузить из Интернета. Вы можете выбрать версию SDK для загрузки. Компилятор, входящий в toolchain, поддерживает компиляцию исходного кода на языке C в устаревшем стандарте — c99 Есть стандартная библиотека языка C, реализующая поддержку большинства функций, например printf. Целевая архитектура для компилятора — Renesas / SuperH SH Приложение, собранное для целевой машины, использует динамический линковщик ld‑uClibc.so.0. Все необходимые для запуска приложений библиотеки содержатся в sdk. Разработчик — STMicroelectronics. Версия GCC — 4.6.3 20120313. Версия GNU LD — 2.22.
Подготовка к прошивке
Поднимаем DHCP (isc‑dhcp‑server) и TFTP (tftpd‑hpa)
В настройках DHCP (/etc/dhcp/dhcpd.conf) указываем файл kreatv‑kernel‑SMARTLABS.bin
В каталог /srv/tftp копируем kreatv‑kernel‑SMARTLABS.bin
Подготавливаем флеш карту
Флеш карту форматируем в ext3
В корень копируем прошивку rt firmvare ver. 5.24246.191016 под именем firmware.bin
Добавляем в корень файл firmware.bin.config с содержимым force=1
В корне создаём каталог PHP‑MOTO1003VIP и копируем туда все четыре файла прошивки
Настраиваем приставку.
Включаем приставку и после включения жмём MENU на пульте
Метод получения сетевого адреса адреса устанавливаем в DHCP
Запрещаем загрузку без получения сетевого адреса
Kernel protocol устанавливаем в 323.
Убеждаемся что Ignore VCI установлен в NO
Стираем старое ПО System → Remove Software. ВНИМАНИЕ! Прежде чем выполнять этот пункт прочитайте все описания и выполните все рекомендации выше. Лучше отключить приставку и вернуться к настройке позже, когда всё будет подготовлено. Эта функция не скрыта по умолчанию и сделать из устройства нерабочий кирпич очень легко.
Сохраняем настройки и отключаем приставку
Процесс прошивки
В процессе прошивки желательно исключить риск пропадания питания. Также заранее подключаем UART, поднимаем Ethernet соединение и подключаем флеш‑карту, поскольку процесс происходит быстрее, чем вы захотите мяукнуть.
Всё подготовлено? Включаем приставку в сеть. Всё внимание на терминал.
System memory: 256 MB Using Slot 1 Unpacking Image ...Done
Первые «шаги»
TFTP: Server node attempt 2 of 2 Connecting to 192.168.1.100 Sending read request for kreatv-kernel-SMARTLABS.bin
Если сервер действительно работает и указанный файл присутствует, загрузка начинается просто. В терминал выводятся указанный в настройках размер блока, полученный размер файла и таймаут.
Negotiation block size = 512 Negotiation transfer size = 3376610 Negotiation data timeout = 5 seconds Download completed Verifying image...
Последние шаги
Image in Local Storage is not up-to-date Storing kernel image in Local Storage
Это значит, что ядро загрузилось и больше не будет дёргаться с TFTP сервера
Kernel loaded successfully Starting new kernel kexec information
Это значит что ядро запустилось. Ловим строчку
KreaTV bootimage is ... Changed, disabling boot until upgrade
Дальнейшая загрузка производиться не будет до тех пор, пока устройство не найдёт прошивку
MASSSTORAGE_DEVICES = /dev/sda kjournald starting. Commit interval 5 seconds EXT3 FS on sda, internal journal EXT3-fs: mounted filesystem with ordered data mode. Successfully mounted /dev/sda to /tmp/sda
Это значит, что флешка примонтировалась.
Upgrade sources: --url="http://upgrade.riskymeije.ru/vip1963x" --url="file:///tmp/sda/firmware.bin"
Это источники, где приставка будет искать прошивку. Если флешка отсутствует, приставка попытается найти прошивку ещё раз.
Splash message: Successfully flashed new firmware. Rebooting ...
Сообщение после прошивки образа rt firmvare ver. 5.24246.191016 (legacy)
Restarting system. Watchdog reset!
Приставка перезагрузится. При следующих перезагрузках приставка будет распаковывать образ из локальной памяти.
Loading kernel image Using Local Storage LS: Image found Will not search for new images on the network Using kernel image in flash Copying 3392028 bytes... Verifying image... Uncompressing image...
Прошивка также подтягивается из локальной памяти
Actual bootimage hash - 3edd21ecd89032b18b51c8472d7c8603 Expected bootimage hash - 3edd21ecd89032b18b51c8472d7c8603 KreaTV bootimage is ... Unchanged.
Выключаем приставку и подготавливаем прошивку PHP‑MOTO1003VIP. Если вы всё сделали так, как написано, достаточно её скопировать из каталога в корень флешки.
Прошиваем с флешки и ожидаем подключения через TELNET
Скрытый текст
Upgrade sources: --url="http://upgrade.riskymeije.ru/vip1963x" --url="file:///tmp/sda/firmware.bin" download/download.c(2580) [ 0 s]: Command line arguments values: download/download.c(2582) [ 0 s]: - vendor: Motorola download/download.c(2584) [ 0 s]: - device: vip19x3 download/download.c(2586) [ 0 s]: - hw revision: 0 download/download.c(2588) [ 0 s]: - version: 7.41484.230401 download/download.c(2597) [ 0 s]: - localization file: /etc/branding/messages.l10n download/download.c(2600) [ 0 s]: - certificates dir: /etc/branding/certificates download/download.c(2602) [ 0 s]: - timeout per retry: 5 download/download.c(2604) [ 0 s]: - max retries: 2 download/source_http.c(0505) [ 0 s]: Not a direct firmware URL http://upgrade.riskymeije.ru/vip1963x download/source_http.c(0173) [ 0 s]: Downloading http://upgrade.riskymeije.ru/vip1963x/check_version_ext?output=text&board=vip19x3&mac=00%3A02%3A9B%3AA9%3A99%3AA5&serial=M91443EG0205¤t_firmware_version=7%2E41484%2E230401 ... download/source_file.c(0040) [ 0 s]: Config file "/tmp/sda/firmware.bin.config" found download/source_http.c(0324) [ 0 s]: Unexpected wget exit code: 256 download/source_http.c(0173) [ 0 s]: Downloading http://upgrade.riskymeije.ru/vip1963x/check_version?output=text&board=vip19x3&mac=00%3A02%3A9B%3AA9%3A99%3AA5&serial=M91443EG0205¤t_firmware_version=7%2E41484%2E230401 ... download/source_http.c(0324) [ 0 s]: Unexpected wget exit code: 256 download/download.c(1296) [ 0 s]: Discarding unresolved http://upgrade.riskymeije.ru/vip1963x download/download.c(1438) [ 0 s]: Callback failed with code -1 download/download.c(2699) [ 0 s]: Firmware candidates: download/download.c(2709) [ 0 s]: - 5.24246.191016 (hw rev. 0) force : file:///tmp/sda/firmware.bin download/download.c(2743) [ 0 s]: Best URL: file:///tmp/sda/firmware.bin download/download.c(0526) [ 0 s]: -1% Please wait. Preparing to download firmware ... download/download.c(2033) [ 0 s]: Verifying firmware checksums and RSA signature ... download/verify.c(0087) [ 0 s]: Loading the CA root certificate ... download/verify.c(0106) [ 0 s]: Loading certificates from "/etc/branding/certificates" ... download/verify.c(0163) [ 0 s]: Loading cerificate from file "/etc/branding/certificates/rostelecom-generic-cert.pem" ... download/download.c(1721) [ 0 s]: Block 1 (signed) @ addr = 0x0x29558278 download/download.c(1722) [ 0 s]: data size : 0x0033c21c (3392028) byte(s) download/download.c(1723) [ 0 s]: header size : 0x00000222 (546) byte(s) download/download.c(1724) [ 0 s]: type : 2 (Linux Kernel Image) download/download.c(1725) [ 0 s]: CRC32 : 0x4bcf4722 download/download.c(1728) [ 0 s]: signature[0] length : 256 download/download.c(1728) [ 0 s]: signature[1] length : 256 download/download.c(1735) [ 0 s]: SHA1 : e4644884a8fdde2df91aadf831c41d5c7ba34553 download/download.c(1738) [ 0 s]: content : unknown download/verify.c(0272) [ 1 s]: Signature check failed download/verify.c(0272) [ 1 s]: Signature check failed download/download.c(1721) [ 1 s]: Block 2 (signed) @ addr = 0x0x298946bc download/download.c(1722) [ 1 s]: data size : 0x02960000 (43384832) byte(s) download/download.c(1723) [ 1 s]: header size : 0x00000222 (546) byte(s) download/download.c(1724) [ 1 s]: type : 3 (Root FS Image) download/download.c(1725) [ 1 s]: CRC32 : 0xd8b09ef7 download/download.c(1728) [ 1 s]: signature[0] length : 256 download/download.c(1728) [ 1 s]: signature[1] length : 256 download/download.c(1735) [ 1 s]: SHA1 : 9dd5db805dda709258f90c1402ba1e416048ce68 download/download.c(1738) [ 1 s]: content : JFFS2 download/verify.c(0272) [ 9 s]: Signature check failed download/verify.c(0272) [ 9 s]: Signature check failed download/download.c(1721) [ 9 s]: Block 3 (signed) @ addr = 0x0x2c1f48e4 download/download.c(1722) [ 9 s]: data size : 0x00005000 (20480) byte(s) download/download.c(1723) [ 9 s]: header size : 0x00000222 (546) byte(s) download/download.c(1724) [ 9 s]: type : 5 (Branding Image) download/download.c(1725) [ 9 s]: CRC32 : 0x052d237b download/download.c(1728) [ 9 s]: signature[0] length : 256 download/download.c(1728) [ 9 s]: signature[1] length : 256 download/download.c(1735) [ 9 s]: SHA1 : 0b864ea8110807b5accac300254cf410faa801b6 download/download.c(1738) [ 9 s]: content : Cramfs download/verify.c(0272) [ 9 s]: Signature check failed download/verify.c(0272) [ 9 s]: Signature check failed download/download.c(0526) [ 9 s]: 75% Please wait. Flashing firmware ... download/download.c(1721) [ 9 s]: Block 1 (signed) @ addr = 0x0x29558278 download/download.c(1722) [ 9 s]: data size : 0x0033c21c (3392028) byte(s) download/download.c(1723) [ 9 s]: header size : 0x00000222 (546) byte(s) download/download.c(1724) [ 9 s]: type : 2 (Linux Kernel Image) download/download.c(1725) [ 9 s]: CRC32 : 0x4bcf4722 download/download.c(1728) [ 9 s]: signature[0] length : 256 download/download.c(1728) [ 9 s]: signature[1] length : 256 download/download.c(1735) [ 9 s]: SHA1 : e4644884a8fdde2df91aadf831c41d5c7ba34553 download/download.c(1738) [ 9 s]: content : unknown File /flash2/.bootimage is successfully written. download/download.c(1721) [ 10 s]: Block 2 (signed) @ addr = 0x0x298946bc download/download.c(1722) [ 10 s]: data size : 0x02960000 (43384832) byte(s) download/download.c(1723) [ 10 s]: header size : 0x00000222 (546) byte(s) download/download.c(1724) [ 10 s]: type : 3 (Root FS Image) download/download.c(1725) [ 10 s]: CRC32 : 0xd8b09ef7 download/download.c(1728) [ 10 s]: signature[0] length : 256 download/download.c(1728) [ 10 s]: signature[1] length : 256 download/download.c(1735) [ 10 s]: SHA1 : 9dd5db805dda709258f90c1402ba1e416048ce68 download/download.c(1738) [ 10 s]: content : JFFS2 download/download.c(2319) [ 10 s]: Preparing to flash block #2 ('rootfs') to '/dev/mtd6' ('rootfs') ... flash_eraseall(): entering...
Проверка прошивки на целостность. В слитой в сеть документации ООО Смартлабс детально описывается структура прошивок для IP приставок
Устанавливаем подключение через TELNET и открываем файл tail -f /var/log/messages. В лог сообщений выводится куча полезной информации.
Поддерживаемые видеорежимы.
Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.135 34 1080p30 16:9 1920x1080p @ 29.97/30Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.136 33 1080p25 16:9 1920x1080p @ 25Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.138 32 1080p24 16:9 1920x1080p @ 23.98/24Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.139 18 576pH 16:9 720x576p @ 50Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.140 3 480pH 16:9 720x480p @ 59.94/60Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.141 20 1080i25 16:9 1920x1080i @ 50Hz* Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.143 5 1080i 16:9 1920x1080i @ 59.94/60Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.144 19 720p50 16:9 1280x720p @ 50Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.145 4 720p 16:9 1280x720p @ 59.94/60Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.146 31 1080p50 16:9 1920x1080p @ 50Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.147 1 DMT0659 4:3 640x480p @ 59.94/60Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.148 22 576iH 16:9 720(1440)x576i @ 50Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.150 21 576i 4:3 720(1440)x576i @ 50Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.151 17 576p 4:3 720x576p @ 50Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.152 7 480iH 16:9 720(1440)x480i @ 59.94/60Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.153 6 480i 4:3 720(1440)x480i @ 59.94/60Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.154 2 480p 4:3 720x480p @ 59.94/60Hz Jan 1 00:01:46 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:46.155 16 1080p 16:9 1920x1080p @ 59.94/60Hz
Поддерживаемые форматы контента.
Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.594 player/info : Supported video codecs: Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.596 player/info : - MPEG-2 video Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.598 player/info : - H.264/14496-10 video (MPEG-4/AVC) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.599 player/info : - 14496-2 Visual (MPEG-4 part 2 video, DivX) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.601 player/info : - SMPTE 421M video (VC1) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.602 player/info : - FLV video Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.603 player/info : - VP6 video Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.604 player/info : - VP6F video Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.606 player/info : - Motion JPEG video Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.633 audio/info : Supported audio codecs: Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.635 audio/info : - ISO/IEC 13818-3 audio (MPEG-2) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.636 audio/info : - ISO/IEC 13818-7 audio with ADTS transport syntax (AAC) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.637 audio/info : - ISO/IEC 14496-3 audio with LATM transport syntax (14496-3/AMD 1) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.639 audio/info : - ATSC A/52 audio (AC3) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.640 audio/info : - ATSC A/52B audio (EAC3) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.641 audio/info : - PCM audio Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.643 audio/info : - LPCM audio Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.644 audio/info : - WMA Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.645 audio/info : - ISO/IEC 11172-3/13818-3 audio (MP3) Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.646 audio/info : - FLAC audio Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.648 audio/info : - Vorbis audio Jan 1 00:01:45 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 10.01.01 00:01:45.649 audio/info : - ISO/IEC 11172-3 audio (MPEG-1)
Воспроизведение контента
Прошивка завершена. Плейлист со ссылкой на произвольный контент можно поместить по пути /mnt/persistent/server/play.m3u8 с следующим содержимым
#EXTM3U8, #EXTINF:-1,Youtube http://127.0.0.1/youtube.m3u8
Далее плейлист необходимо добавить через веб интерфейс http://IP_адрес_приставки/player.php
Поддерживается воспроизведение по протоколам FTP, HTTP, UDP (Multicast), RTSP (без авторизации). TLS не поддерживается. Поддерживается стандарт сжатия H.264 и не поддерживается H.265.
Выключаем приставку, подключаем видеовыход и Интернет. Приставкой можно пользоваться.

С жителями страны, которые просто любят смотреть кастомный контент на телевизоре, мы прощаемся, для остальных технических гурманов мы продолжим.
И вот о чём расскажем далее...
Первая программа для IPTV приставки
Напишем исходный код и сохраним в файл main.c с надеждой, что выстрелит.
#include <stdio.h> #include <stdlib.h> int main(void) { printf("%s","Hello World\n"); }
«Ты меня учить будешь? Свободен. Нужно будет — позвоню.» © К/ф «Бой с тенью»
Людей можно понять. Но для начала скомпилируем код. Для этого распакуем SDK и зададим переменные окружения.
sh4gcc="/toolchain/st40/2.5.0/bin/sh4-motorola-linux-uclibc-gcc" sh4ld="/toolchain/st40/2.5.0/bin/sh4-motorola-linux-uclibc-ld" sh4readelf="/toolchain/st40/2.5.0/bin/sh4-motorola-linux-uclibc-readelf" sh4nm="/toolchain/st40/2.5.0/bin/sh4-motorola-linux-uclibc-nm" sh4strip="/toolchain/st40/2.5.0/bin/sh4-motorola-linux-uclibc-strip"
Подключим библиотеки
LDFLAGS=/home/sandrabullok/motorola_developer/develop/tmp.ArC6.d/toolchain/st40/2.5.0/sh4-motorola-linux-uclibc/sys-root/usr/lib/crt1.o -L/home/sandrabullok/motorola_developer/develop/tmp.ArC6.d/toolchain/st40/2.5.0/lib -L/home/sandrabullok/motorola_developer/develop/tmp.ArC6.d/toolchain/st40/2.5.0/sh4-motorola-linux-uclibc/sys-root/lib -L/home/sandrabullok/motorola_developer/develop/tmp.ArC6.d/toolchain/st40/2.5.0/sh4-motorola-linux-uclibc/sys-root/usr/lib -L/home/sandrabullok/motorola_developer/develop/tmp.ArC6.d/toolchain/st40/2.5.0/sh4-motorola-linux-uclibc/lib -L. -L/home/sandrabullok/motorola_developer/develop/tmp.ArC6.d/toolchain/st40/2.5.0/lib/gcc/sh4-motorola-linux-uclibc/4.6.3 -lc -lgcc -ldl -lm -lutil -lnsl -lcrypt -lresolv -luargp -lrt -lpthread -rpath . --dynamic-linker ld-uClibc.so.0
Теперь можно компилировать
sh4gcc -c main.c -o main.o sh4ld $LDFLAGS main.o -o main.bin
Полученный исполняемый файл не получится запустить, он предназначается для другой архитектуры. В чём мы сейчас убедимся.
sh-5.1$ $sh4readelf -h main.bin ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Renesas / SuperH SH Version: 0x1 Entry point address: 0x4003b4 Start of program headers: 52 (bytes into file) Start of section headers: 1536 (bytes into file) Flags: 0x9, sh4 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 6 Size of section headers: 40 (bytes) Number of section headers: 16 Section header string table index: 13
Копируем исполняемый файл в единый каталог вместе с библиотеками
итого 4236 -rwxrwxr-x 1 sandrabullok sandrabullok 4038 июл 22 13:07 app.bin -r-xr-xr-x 1 sandrabullok sandrabullok 96925 июл 22 13:07 ld-uClibc.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 28676 июл 22 13:07 libcrypt.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 3200747 июл 22 13:07 libc.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 32815 июл 22 13:07 libdl.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 160246 июл 22 13:07 libm.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 6219 июл 22 13:07 libnsl.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 567364 июл 22 13:07 libpthread.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 6234 июл 22 13:07 libresolv.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 96503 июл 22 13:07 librt.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 96053 июл 22 13:07 libuargp.so.0 -r-xr-xr-x 1 sandrabullok sandrabullok 14626 июл 22 13:07 libutil.so.0
Особенно заостряю ваше внимание на библиотеке ld‑uClibc.so.0. Динамический компоновщик редактирует связи с динамическими библиотеками непосредственно в памяти устройства. Сделано так, возможно, для экономии оперативной памяти: оверлей программы подгружается, когда он необходим, в произвольном порядке и на лету редактируется. Если данную библиотеку не подключить, программа будет вылетать в SEGFAULT, потому что при запуске программа делает первый шаг и делает его в пропасть — в таблицах адресов ничего нет.
Далее начинается то, ради чего полстатьи маялись. Упакуйте в TAR архив и разместите на HTTP сервере. Устанавливаем подключение с приставкой через TELNET и скачиваем архив командой wget. Например
wget http://192.168.1.100/$APP_NAME.tar tar -xf $APP_NAME.tar rm $APP_NAME.tar ls - la
Запускаем программу и видим текст
Hello World
Эта программа работает на целевой машине (IPTV приставке MOTOROLA VIP1003)!
А это значит, что технически возможно портировать крупный проект.
Портирование FFmpeg на архитектуру SuperH SH
Есть проблема. Приставка не может воспроизвести контент с источника RTSP потока, требующего basic аутентификацию.
Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: OPTIONS rtsp://login:pass@[IP]/path RTSP/1.0 Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: User-Agent: Restream/7.999.9999 (vip19x3; Motorola_VIP1003) SmartSDK/1.5.63-rt-38-22-g950636f Qt/4.7.3 API/0.30.0 Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: CSeq: 1 Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 18.09.06 19:50:50.818 rtsp/info : Response Header: Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: RTSP/1.0 200 OK Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: CSeq: 1 Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: Public: OPTIONS, DESCRIBE, PLAY, SETUP, TEARDOWN, SET_PARAMETER, GET_PARAMETER Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 18.09.06 19:50:50.823 rtsp/debug : Outgoing RTSP command: Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: DESCRIBE rtsp://login:pass@[IP]/path RTSP/1.0 Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: Accept: application/x-rtsp-mh, application/sdp Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: User-Agent: Restream/7.999.9999 (vip19x3; Motorola_VIP1003) SmartSDK/1.5.63-rt-38-22-g950636f Qt/4.7.3 API/0.30.0 Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: CSeq: 2 Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: Q: Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 18.09.06 19:50:50.833 rtsp/info : Response Header: Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: RTSP/1.0 401 Unauthorized Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: CSeq: 2 Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: WWW-Authenticate: Digest realm="RTSP SERVER", nonce="1b5eff39c311f943304b9c10bc8efba7", stale="FALSE" Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: WWW-Authenticate: Basic realm="RTSP SERVER" Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: Date: Fri, 03 Jul 2026 18:23:12 GMT Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: A: Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 18.09.06 19:50:50.836 rtsp/error : invalid response status code 401 from RTSP server. Aborting ... Sep 6 16:50:50 vip19x3-00029BA999A5-7_999_9999 local1.debug app: 18.09.06 19:50:50.838 rtsp/error : RTSP protocol failure !!!
А можно ли добавить в приставку поддержку какого‑нибудь недостающего сетевого протокола, например. Теперь есть полные основания портировать для IPTV приставки серьёзный проект. И таким проектом будет FFmpeg.
Скачиваем FFmpeg далее выполняем. Пока что компиляция происходит для компьютера.
git checkout 52c7366c83aba4dc92ceedecbee592d629c98e29 ./configure make
Коммит древний — 2012 года, если не ошибаюсь и поддерживает устаревший стандарт языка C — std99. Новые коммиты будут падать с ошибками компиляции.
Свободной памяти в устройстве немного, так что придётся поторговаться. Отключаем по умолчанию все кодеры, миксеры, поддержку устройств и сетевых протоколов. И выбираем только то что нужно.
# Individual component option INDIVIDUAL_OPTIONS="" INDIVIDUAL_OPTIONS+="--disable-encoders " INDIVIDUAL_OPTIONS+="--disable-decoders " INDIVIDUAL_OPTIONS+="--disable-muxers " INDIVIDUAL_OPTIONS+="--disable-demuxers " INDIVIDUAL_OPTIONS+="--disable-protocols " INDIVIDUAL_OPTIONS+="--disable-devices " INDIVIDUAL_OPTIONS+="--enable-protocol=rtp " INDIVIDUAL_OPTIONS+="--enable-protocol=udp " INDIVIDUAL_OPTIONS+="--enable-muxer=mpegts " INDIVIDUAL_OPTIONS+="--enable-demuxer=rtsp "
В расширении флагов компоновки указываем библиотеки с поддержкой целевой архитектуры.
EXTRA_LDFLAGS="-L." EXTRA_LDFLAGS+="-L${TOOLCHAIN_PATH}/sh4-motorola-linux-uclibc/lib " EXTRA_LDFLAGS+="-L${TOOLCHAIN_PATH}/sh4-motorola-linux-uclibc/sys-root/lib " EXTRA_LDFLAGS+="-L${TOOLCHAIN_PATH}/sh4-motorola-linux-uclibc/sys-root/usr/lib " EXTRA_LDFLAGS+="-L${TOOLCHAIN_PATH}/lib/gcc/sh4-motorola-linux-uclibc/4.6.3 " EXTRA_LDFLAGS+="-lc -lgcc -ldl -lm -lutil -lnsl -lcrypt -lresolv -luargp " EXTRA_LDFLAGS+="-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample "
Давайте посмотрим сюда.
EXTRA_CXXFLAGS+="-std=c99 " # Assume that the input sources are for <standard> EXTRA_CXXFLAGS+="-m4 " # Generate SH4 code EXTRA_CXXFLAGS+="-mglibc " # Use GNU C library EXTRA_CXXFLAGS+="-pthread "
Флаги -std=c99 и -m4 предписывают системе сборки компилировать код для целевой архитектуры и использовать совместимый стандарт языка C. Чем библиотека glibc лучше или хуже чем libc не понимаю.
Полный код скрипта настройки сборки.Компилироваться будет только ffmpeg
Скрытый текст
#!/bin/bash # Head # ARCH=sh CPU=STx7105 TARGET_OS=linux TOOLCHAIN_PATH=~/ffmpeg/toolchain/st40/2.5.0 # $TOOLCHAIN_PATH CROSS_PREFIX="${TOOLCHAIN_PATH}/bin/sh4-motorola-linux-uclibc-" CROSS_PREFIX_ENABLED=0 ENABLE_CROSS_COMPILE=1 PROGS_SUFFIX='' DIST=~/ffmpeg/dist ######## if [ $ENABLE_CROSS_COMPILE -ne 0 ] then LOG=configure_cross.log else LOG=configure_nocross.log fi if [ $CROSS_PREFIX_ENABLED -eq 0 ] then ### set use tools from toolchain ### NM=$TOOLCHAIN_PATH/bin/sh4-motorola-linux-uclibc-nm #use nm tool NM [nm -g] AR=$TOOLCHAIN_PATH/bin/sh4-motorola-linux-uclibc-ar #use archive tool AR [ar] AS=$TOOLCHAIN_PATH/bin/sh4-motorola-linux-uclibc-as #use assembler AS [] #LN_S STRIP=$TOOLCHAIN_PATH/bin/sh4-motorola-linux-uclibc-strip #use strip tool STRIP [strip] CC=$TOOLCHAIN_PATH/bin/sh4-motorola-linux-uclibc-gcc #use C compiler CC [gcc] STDC=c99 #use C standard STDC [c17] CXX=$TOOLCHAIN_PATH/bin/sh4-motorola-uclibc-g++ #use C compiler CXX [g++] STDCXX=c++17 #use C standard STDCXX [c++17] LD=$TOOLCHAIN_PATH/bin/sh4-motorola-linux-uclibc-ld #use linker LD [] RANLIB=$TOOLCHAIN_PATH/bin/sh4-motorola-linux-uclibc-ranlib #use ranlib RANLIB [ranlib] SIZE=$TOOLCHAIN_PATH/bin/sh4-motorola-linux-uclibc-size ### set use tools from toolchain ### fi #PATH=$PATH:${TOOLCHAIN_PATH}/bin:${DIST}/bin BSG_SRC=../../.. BSG_INCLUDE=${DIST}/st40/include # Standard options STANDARD_OPTIONS="" #STANDARD_OPTIONS+="--quiet " STANDARD_OPTIONS+="--logfile=$LOG " # Program options PROGRAM_OPTIONS="" # Documentation options: DOCUMENTATION_OPTIONS="" DOCUMENTATION_OPTIONS+="--disable-doc " # do not build documentation DOCUMENTATION_OPTIONS+="--disable-htmlpages " # do not build HTML documentation pages DOCUMENTATION_OPTIONS+="--disable-manpages " # do not build man documentation pages DOCUMENTATION_OPTIONS+="--disable-podpages " # do not build POD documentation pages DOCUMENTATION_OPTIONS+="--disable-txtpages " # do not build text documentation pages # Component options COMPONENT_OPTIONS="" COMPONENT_OPTIONS+="--disable-swscale " COMPONENT_OPTIONS+="--disable-avresample " COMPONENT_OPTIONS+="--disable-avdevice " COMPONENT_OPTIONS+="--disable-avfilter " # Individual component option INDIVIDUAL_OPTIONS="" INDIVIDUAL_OPTIONS+="--disable-encoders " INDIVIDUAL_OPTIONS+="--disable-decoders " INDIVIDUAL_OPTIONS+="--disable-muxers " INDIVIDUAL_OPTIONS+="--disable-demuxers " INDIVIDUAL_OPTIONS+="--disable-protocols " INDIVIDUAL_OPTIONS+="--disable-devices " INDIVIDUAL_OPTIONS+="--enable-protocol=rtp " INDIVIDUAL_OPTIONS+="--enable-protocol=udp " INDIVIDUAL_OPTIONS+="--enable-muxer=mpegts " INDIVIDUAL_OPTIONS+="--enable-demuxer=rtsp " # External library support ELIBRARY_SUPPORT="" ELIBRARY_SUPPORT+="--disable-sdl2 " # disable sdl2 [autodetect] # Toolchain options TOOLCHAIN_OPTIONS="" if [ $ENABLE_CROSS_COMPILE -ne 0 ] then echo 'Set flag ENABLE_CROSS_COMPILE' TOOLCHAIN_OPTIONS+="--enable-cross-compile " #assume a cross-compiler is used fi TOOLCHAIN_OPTIONS+="--arch=$ARCH " # select architecture [] TOOLCHAIN_OPTIONS+="--cpu=$CPU " # select the minimum required CPU (affects # instruction selection, may crash on older CPUs) if [ ! $CROSS_PREFIX_ENABLED -eq 0 ] then echo 'Set flag CROSS_PREFIX_ENABLED' TOOLCHAIN_OPTIONS+="--cross-prefix=$CROSS_PREFIX " # use PREFIX for compilation tools [] fi TOOLCHAIN_OPTIONS+="--build-suffix=$PROGS_SUFFIX " # program name suffix [] TOOLCHAIN_OPTIONS+="--target-os=$TARGET_OS " #compiler targets OS [] #TOOLCHAIN_OPTIONS+="--sysroot=$SYSROOT " #root of cross-build tree #TOOLCHAIN_OPTIONS+="--sysinclude=$SYSINCLUDE " #location of cross-build system headers #TOOLCHAIN_OPTIONS+="--target-exec=$TARGET_EXEC " #command to run executables on target #TOOLCHAIN_OPTIONS+="--target-path=$TARGET_PATH " #path to view of build directory on target #TOOLCHAIN_OPTIONS+="--target-samples=$TARGET_SAMPLES " #path to samples directory on target #TOOLCHAIN_OPTIONS+="--tempprefix=$TEMPPREFIX " #force fixed dir/prefix instead of mktemp for checks #TOOLCHAIN_OPTIONS+="--toolchain=$TOOLCHAIN " #set tool defaults according to NAME #(<tool>[-sanitizer[-...]], e.g. clang-asan-ubsan #tools: gcc, clang, llvm, msvc, icl, gcov, llvm-cov, # valgrind-memcheck, valgrind-massif, hardened #sanitizers: asan, fuzz, lsan, msan, tsan, ubsan) if [ $CROSS_PREFIX_ENABLED -eq 0 ] then TOOLCHAIN_OPTIONS+="--nm=$NM --ar=$AR --as=$AS --cc=$CC --ld=$LD " #TOOLCHAIN_OPTIONS+="--ln_s=$LN_S " #use symbolic link tool LN_S [ln -s -f] #TOOLCHAIN_OPTIONS+="--windres=$WINDRES " #use windows resource compiler WINDRES [windres] #TOOLCHAIN_OPTIONS+="--x86asmexe=$X86ASMEXE " #use nasm-compatible assembler EXE [nasm] #TOOLCHAIN_OPTIONS+="--objcc=$OBJCC " #use ObjC compiler OCC [gcc] #TOOLCHAIN_OPTIONS+="--dep-cc=$DEPCC " #use dependency generator DEPCC [gcc] #TOOLCHAIN_OPTIONS+="--glslc=$GLSLC " #use GLSL compiler GLSLC [glslc] #TOOLCHAIN_OPTIONS+="--nvcc=$NVCC " #use Nvidia CUDA compiler NVCC or clang [] #TOOLCHAIN_OPTIONS+="--metalcc=$METALCC " #use metal compiler METALCC [xcrun -sdk macosx metal] #TOOLCHAIN_OPTIONS+="--metallib=$METALLIB " #use metal linker METALLIB [xcrun -sdk macosx metallib] #TOOLCHAIN_OPTIONS+="--pkg-config=$PKGCONFIG " #use pkg-config tool PKGCONFIG [pkg-config] #TOOLCHAIN_OPTIONS+="--pkg-config-flags=$PKGCONFIG_FLAGS " #pass additional flags to pkgconf [] #TOOLCHAIN_OPTIONS+="--doxygen=$DOXYGEN " #use DOXYGEN to generate API doc [doxygen] #TOOLCHAIN_OPTIONS+="--makeinfo=$MAKEINFO " #use MAKEINFO to generate documentation [makeinfo] # --strip=$STRIP --cxx=$CXX --stdcxx=$STDCXX --stdc=$STDC --ranlib=$RANLIB fi HOST_CC="gcc" #use host C compiler HOSTCC HOST_CFLAGS="-m32" #use HCFLAGS when compiling for host HOST_CXX="g++" HOST_CPPFLAGS="" #use HCPPFLAGS when compiling for host HOST_LD="ld" #use host linker HOSTLD HOST_LDFLAGS="-m32" #use HLDFLAGS when linking for host HOST_EXTRALIBS="" #use libs HLIBS when linking for host HOST_OS="" #compiler host OS [] TOOLCHAIN_OPTIONS+="--host-cc=$HOST_CC " #use host C compiler HOSTCC TOOLCHAIN_OPTIONS+="--host-cflags=$HOST_CFLAGS " #use HCFLAGS when compiling for host #TOOLCHAIN_OPTIONS+="--host-cppflags=$HOST_CPPFLAGS " #use HCPPFLAGS when compiling for host TOOLCHAIN_OPTIONS+="--host-ld=$HOST_LD " #use host linker HOSTLD TOOLCHAIN_OPTIONS+="--host-ldflags=$HOST_LDFLAGS " #use HLDFLAGS when linking for host #TOOLCHAIN_OPTIONS+="--host-extralibs=$HOST_EXTRALIBS " #use libs HLIBS when linking for host TOOLCHAIN_OPTIONS+="--host-os=$HOST_OS " #compiler host OS [] ### set linked library ### EXTRA_LDFLAGS="-L." EXTRA_LDFLAGS+="-L${TOOLCHAIN_PATH}/sh4-motorola-linux-uclibc/lib " EXTRA_LDFLAGS+="-L${TOOLCHAIN_PATH}/sh4-motorola-linux-uclibc/sys-root/lib " EXTRA_LDFLAGS+="-L${TOOLCHAIN_PATH}/sh4-motorola-linux-uclibc/sys-root/usr/lib " EXTRA_LDFLAGS+="-L${TOOLCHAIN_PATH}/lib/gcc/sh4-motorola-linux-uclibc/4.6.3 " EXTRA_LDFLAGS+="-lc -lgcc -ldl -lm -lutil -lnsl -lcrypt -lresolv -luargp " EXTRA_LDFLAGS+="-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample " #EXTRA_LDFLAGS+="-L${DIST}/st40/lib " #EXTRA_LDFLAGS+="-L${DIST}/st40/3pp/lib " #EXTRA_LDFLAGS+="-L${DIST}/st40/vip19x3/lib " #EXTRA_LDFLAGS+="-L${DIST}/st40/3pp/vip19x3/lib " ### set linked library ### ENV="LD_LIBRARY_PATH=~/FFmpeg/toolchain/st40/2.5.0/sh4-motorola-linux-uclibc/lib" #; \ #/usr/local/motorola/toolchain/st40/2.5.0/sh4-motorola-linux-uclibc/sys-root/usr/lib; \ #~/FFmpeg/dist/st40/lib; \ #~/FFmpeg/dist/st40/3pp/lib; \ #~/FFmpeg/dist/st40/vip19x3/lib; \ #~/FFmpeg/dist/st40/3pp/vip19x3/lib " echo $ENV EXTRA_CFLAGS=" -I. " EXTRA_CFLAGS+="-I${DIST}/st40/include " EXTRA_CFLAGS+="-I${DIST}/st40/3pp/vip19x3/include " EXTRA_CFLAGS+="-I${DIST}/st40/3pp/vip19x3/linux/include " EXTRA_CFLAGS+="-I${DIST}/st40/3pp/include " EXTRA_CFLAGS+="-I${DIST}/stb-noarch/include " EXTRA_CFLAGS+="-I${DIST}/stb-noarch/3pp/include " EXTRA_CFLAGS+="-I${DIST}/noarch/include " EXTRA_CFLAGS+="-I${DIST}/noarch/3pp/include " EXTRA_CFLAGS+="-g -Os -finline-limit=50 -D__ST40__=1 -D__VIP19X3__=1 " EXTRA_CFLAGS+="-O0 " # Set optimization level to <number> EXTRA_CFLAGS+="-std=c99 " # Assume that the input sources are for <standard> EXTRA_CFLAGS+="-m4 " # Generate SH4 code EXTRA_CFLAGS+="-mglibc " # Use GNU C library EXTRA_CFLAGS+="-pthread " EXTRA_CXXFLAGS="-fvisibility-inlines-hidden -I. " EXTRA_CXXFLAGS+="-I${DIST}/st40/include " EXTRA_CXXFLAGS+="-I${DIST}/st40/3pp/vip19x3/include " EXTRA_CXXFLAGS+="-I${DIST}/st40/3pp/vip19x3/linux/include " EXTRA_CXXFLAGS+="-I${DIST}/st40/3pp/include " EXTRA_CXXFLAGS+="-I${DIST}/stb-noarch/include " EXTRA_CXXFLAGS+="-I${DIST}/stb-noarch/3pp/include " EXTRA_CXXFLAGS+="-I${DIST}/noarch/include " EXTRA_CXXFLAGS+="-I${DIST}/noarch/3pp/include " EXTRA_CXXFLAGS+="-g -Os -finline-limit=50 -D__ST40__=1 -D__VIP19X3__=1 " EXTRA_CXXFLAGS+="-g -Os -finline-limit=50 -D__ST40__=1 -D__VIP19X3__=1 " EXTRA_CXXFLAGS+="-O0 " # Set optimization level to <number> EXTRA_CXXFLAGS+="-std=c99 " # Assume that the input sources are for <standard> EXTRA_CXXFLAGS+="-m4 " # Generate SH4 code EXTRA_CXXFLAGS+="-mglibc " # Use GNU C library EXTRA_CXXFLAGS+="-pthread " echo "EXTRA_LDFLAGS=$EXTRA_LDFLAGS" TOOLCHAIN_OPTIONS+="--extra-ldflags=\"$EXTRA_LDFLAGS\" " #add ELDFLAGS to LDFLAGS [] echo "EXTRA_CFLAGS=$EXTRA_CFLAGS" TOOLCHAIN_OPTIONS+="--extra-cflags=\"$EXTRA_CFLAGS\" " #add ECFLAGS to CFLAGS [] echo "EXTRA_CXXFLAGS=$EXTRA_CXXFLAGS" TOOLCHAIN_OPTIONS+="--extra-cxxflags=\"$EXTRA_CXXFLAGS\" " #add ECFLAGS to CXXFLAGS [] CPPFLAGS=" -I. " CPPFLAGS+="-I${DIST}/st40/include " CPPFLAGS+="-I${DIST}/st40/3pp/vip19x3/include " CPPFLAGS+="-I${DIST}/st40/3pp/vip19x3/linux/include " CPPFLAGS+="-I${DIST}/st40/3pp/include " CPPFLAGS+="-I${DIST}/stb-noarch/include " CPPFLAGS+="-I${DIST}/stb-noarch/3pp/include " CPPFLAGS+="-I${DIST}/noarch/include " CPPFLAGS+="-I${DIST}/noarch/3pp/include" #TOOLCHAIN_OPTIONS+="--extra-objcflags=$EXTRA_OBJFLAGS " #add FLAGS to OBJCFLAGS [] #TOOLCHAIN_OPTIONS+="--extra-ldexeflags=$EXTRA_LDEXEFLAGS " #add ELDFLAGS to LDEXEFLAGS [] #TOOLCHAIN_OPTIONS+="--extra-ldsoflags=$EXTRA_LDSOFLAGS " #add ELDFLAGS to LDSOFLAGS [] #TOOLCHAIN_OPTIONS+="--extra-libs=$EXTRA_LIBS " #add ELIBS [] #TOOLCHAIN_OPTIONS+="--extra-version=$EXTRA_VERSION " #version string suffix [] #TOOLCHAIN_OPTIONS+="--optflags=$OPTFLAGS " #override optimization-related compiler flags #TOOLCHAIN_OPTIONS+="--glslcflags=$GLSLCFLAGS " #extra glslc flags [] #TOOLCHAIN_OPTIONS+="--nvccflags=$NVCCFLAGS " #override nvcc flags [] #TOOLCHAIN_OPTIONS+="--build-suffix=$BUILD_SUFFIX " #library name suffix [] #TOOLCHAIN_OPTIONS+="--enable-pic " #build position-independent code #TOOLCHAIN_OPTIONS+="--enable-thumb " #compile for Thumb instruction set #TOOLCHAIN_OPTIONS+="--enable-lto[=$arg] " #use link-time optimization TOOLCHAIN_OPTIONS+="--env=\"$ENV\" " #override the environment variables #TOOLCHAIN_OPTIONS+="--disable-response-files #Don't pass the list of objects to linker in a file [autodetect] # Optimization options OPTIMIZATION_OPTIONS="" OPTIMIZATION_OPTIONS+="--disable-mmx " OPTIMIZATION_OPTIONS+="--disable-sse " OPTIMIZATION_OPTIONS+="--disable-sse2 " OPTIMIZATION_OPTIONS+="--disable-sse3 " OPTIMIZATION_OPTIONS+="--disable-sse4 " OPTIMIZATION_OPTIONS+="--disable-avx " #OPTIMIZATION_OPTIONS+="--disable-avx2 " #OPTIMIZATION_OPTIONS+="--disable-avx512 " #OPTIMIZATION_OPTIONS+="--disable-fma3 " #OPTIMIZATION_OPTIONS+="--disable-fma4 " # Other OTHER="" OTHER+="--disable-zlib " # All options OPTIONS="" echo "STANDARD_OPTIONS=$STANDARD_OPTIONS" OPTIONS+=$STANDARD_OPTIONS echo "PROGRAM_OPTIONS=$PROGRAM_OPTIONS" OPTIONS+=$PROGRAM_OPTIONS echo "DOCUMENTATION_OPTIONS=$DOCUMENTATION_OPTIONS" OPTIONS+=$DOCUMENTATION_OPTIONS echo "COMPONENT_OPTIONS=$COMPONENT_OPTIONS" OPTIONS+=$COMPONENT_OPTIONS echo "INDIVIDUAL_OPTIONS=$INDIVIDUAL_OPTIONS" #OPTIONS+=$INDIVIDUAL_OPTIONS echo "ELIBRARY_SUPPORT=$ELIBRARY_SUPPORT" OPTIONS+=$ELIBRARY_SUPPORT echo "OTHER=$OTHER" OPTIONS+=$OTHER if [ $ENABLE_CROSS_COMPILE -ne 0 ] then echo "TOOLCHAIN_OPTIONS=$TOOLCHAIN_OPTIONS" OPTIONS+=$TOOLCHAIN_OPTIONS fi echo "OPTIMIZATION_OPTIONS=$OPTIMIZATION_OPTIONS" OPTIONS+=$OPTIMIZATION_OPTIONS # Cmdline echo '*** Cmdline ***' CMDLINE="./configure $OPTIONS" echo Usage: $CMDLINE echo "Log: $LOG" echo "$(date): Execute configure... " eval $CMDLINE 1>$LOG 2>$LOG echo "Exit code (configure): $?" [ ! $?=0 ] && exit echo "$(date): Execute make " #make clean #make 1>>$LOG 2>>$LOG # -n --recon echo "Exit code (make): $?" echo "$(date): Done "
Makefile требуется изменить следующим образом.
$(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF) $(info file $<) # $(CP) $< $@ # $(STRIP) $@
%$(PROGSSUF)_g$(EXESUF): %.o $(FF_DEP_LIBS) $(info Запуск сборки...) $(info linker $(LD)) $(info output $(LD_O)) $(info objects $(OBJS-$*)) # instead $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS)
Среда сборки вместо линковки выведет необходимую информацию. Линкуем вручную. Там есть какие‑то конфликтующие зависимости, я даже разбираться не стал. Заработало — и всё тут.
После успешной сборки копируем архив с исполняемым файлом и сопутствующими. Запускаем? Или не хочется опять поймать сегфолт какой‑нибудь?
# ./ffmpeg --help ffmpeg version N-83801-g52c7366c83 Copyright (c) 2000-2017 the FFmpeg developers built with gcc 4.6.3 (STMicroelectronics Base) 20120313
Огонь! Программа работает даже под нагрузкой, что далее будет подтверждено.
Воспроизведение контента
Произведём предварительные настройки сетевых буферов
sudo sysctl -w net.core.wmem_max=10485760 sudo sysctl -w net.core.wmem_default=1048576 sudo sysctl -w net.core.rmem_max=10485760 sudo sysctl -w net.core.rmem_default=1048576
Сейчас приставка сможет воспроизвести контент с источника RTSP требующего basic авторизации. В прошивке не было такой возможности. Добавляем плейлист.
#EXTM3U8, #EXTINF:-1,Youtube udp://127.0.0.1:1234
и запускаем FFmpeg
/root/ffmpeg/ffmpeg -buffer_size 1M -r 50 -i rtsp://login:password@[IP]/[path] -c copy -f mpegts udp://127.0.0.1:1234?pkt_size=1316
Логи с сообщениями приложения, к сожалению, не сохранились. Демультиплексированный RTSP поток датаграмм мультиплексируется в UDP поток контейнеров MPEGTS и отдаётся в адрес локальной петли. Перекодирование потока не требуется. Далее поток остаётся выбрать в меню и включить воспроизведение. UDP поток хорош тем, что при сбоях передачи воспроизведение не останавливается. Приложение может отправить поток в петлю в любой момент, и видеосигнал будет восстановлен.
Проблема портирования приложений для архитектуры SuperH SH
В linux присутствует устройство фреймбуфера /dev/fb0, /dev/fb1. Они предназначены для HD и SD режимов. Настроить режим можно утилитой fbset
fbset -fb /dev/fb0 -g 1920x1200x32
Фреймбуферы доступны до запуска фирменного приложения Rostelecom.
Некоторые медиаплееры с открытым исходным кодом поддерживают вывод во фреймбуфер. Например:
mplayer -vo fbdev video.avi
Но портировать подобные проекты сложно. Кодовые базы проектов требуют поддержки стандартов c11, c17 от компиляторов для целевой архитектуры.
Спасибо за внимание

