Пишем первую программу… для IPTV приставки

Приветствую профессиональное сообщество Хабра. В этой статье описана прошивка 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 от компиляторов для целевой архитектуры.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.