Одноплатные компьютеры своим появлением взяли на себя огромное количество задач и с каждым днём решают всё больше наших проблем. Но многие окружающие нас бытовые устройства являются одноплатными компьютерами с практически идентичной начинкой и телевизионные приставки классический тому пример.
Когда-то я приобрел ТВ приставку X96 Max Plus 100W на Android, чтобы потестить вдоль и поперек и скоро пришел к тому, что классическое ее применение для просмотра мультиков и Android игр мне не интересно. Очень захотелось установить Linux и использовать приставку как обычный мини-компьютер. Вот для таких энтузиастов, кто хочет установить Linux на телевизионную приставку, превратив ее в сервер или даже в десктопный компьютер, я и расскажу свою историю. История отличается от всех остальных подобных реалистичностью, когда результата по инструкции достичь не удается.
Этот эксперимент можно повторить даже не затрагивая работоспособность установленной системы Android лишь подготовив загрузочный носитель и загрузившись с него.
Если вдруг читатель не знает зачем нужен такой мини-компьютер, поясню: такой тихий и экономичный гаджет превосходен как сервер умного дома на HomeAssistant, домашний веб-сервер на nginx, сервер телефонии на Asterisk, для сбора статистики с метеостанции, рутер, игровая консоль на Retro-Pi, медиацентр, для конвертирования RTSP видеопотока с камеры в HLS для встраивания на веб-страницу, TorrServer для просмотра фильмов прямо с торрентов. Благо, ресурсов у современных приставок более чем достаточно для большинства подобных задач.
Представьте себе сколько таких телевизионных приставок выбрасывается провайдерами по истечении контракта, ведь пользователи по контракту зачастую обязаны ее вернуть. Но даже купить ТВ приставку, такую как Transpeed 6k (на Алиэкспресс называется H616 по имени процессора), как минимум не дороже, чем ее клон-одноплатник Orange Pi Zero 2 на том же процессоре. Такой компьютер буде�� в красивом корпусе и с плюшками вроде пульта, HDMI кабеля и БП. Вот описание незначительных различий между этими устройствами: http://nskhuman.ru/allwinner/fdt/basefdt.php


Но вернемся к приставке, которая у меня была и над которой я проводил свои эксперименты. Исследование и вскрытие показало что внутри приставки X96 Max Plus 100W:
CPU: Amlogic S905X3 quad-core ARM Cortex A55
GPU: ARM Mali-G31MP
Radio module: W522A
Memory: DDR3 4GB, FLASH 64GB
Support 10/100M Ethernet, 2.4 and 5G WiFi, BT4.0;
USB3.0 x 1, USB2.0 x 1, TF Card
HDMI, AV, SPDIF
Фото с форума Armbian похожей приставки, с абсолютно тем же названием. Даже на плате кодовое название совпадает: Q53X_141 V4.1 20112. Но моя плата отличается тем, что на борту 64 гига EMMC и отсутствует гигабитный PHY чип неподалеку от ethernet интерфейса. Вместо внешнего PHY чипа для сети используются встроенные возможности SoC. Это важно и к этому вопросу еще вернемся.

Обозреваемая приставка очень близка по характеристикам к одноплатнику Banana Pi M2 Pro и Banana M5. Но использование официальной прошивки Armbian под эту платформу я на приставке даже не проверял и пошел другим путем. Было бы интересно узнать, если кто пробовал подобное.
Armbian
За небогатым выбором ОС остановился на Armbian - Debian для ARM компьютеров. Взял готовый образ под свой процессор, но "искаропки" он конечно же не завелся:
https://github.com/ophub/amlogic-s9xxx-armbian/releases/
Пришлось разбираться во всех нюансах ARM платформы, которая совсем уж не похожа на столь привычный и знакомый нам с детства x86. Самое первое - это отсутствие привычного меню для настройки BIOS/UEFI. Зато на таких платах всегда есть UART контакты RX/TX, к которым можно подпаяться и подключиться USB UART адаптером, получив доступ к консоли устройства. Если вам повезет и подготовленный загрузочный носитель заработает, то паять UART не придется.
По инструкции установки Armbian на приставку все выглядит очень просто: скачать образ, записать его на носитель, вставить носитель в слот приставки, загрузиться в Андроид и выбрать обновление с внешнего носителя, перезагрузиться, подключиться через ssh к своему новому мини-компьютеру на Armbian и начать настраивать под себя. Увы, на практике по этой инструкции моя приставка не показывала абсолютно никаких признаков жизни ни через HDMI, ни на своем встроенном дисплее с часиками. Выглядит как кирпич.
Чтобы заставить приставку грузиться с флэшки у меня прошел следующий трюк: выключаю питание приставки, зубочисткой зажимаю кнопку внутри входа AV (mini-jack 3.5), включаю питание. Но официальная рекомендация по установке Armbian твердит что нужно это делать через режим разработчика Android (позже будет о том, как это сделать).
Попытку загрузки с флэшки я распознаю по тому факту, что перестает загружаться Android. Чтобы сделать носитель загрузочным, скрипты должны найти файл u-boot.ext. Изначально такого файла нет, потому что образ системы универсален: есть коллекция таких файлов под различные устройства. Я попробовал переименовывать имеющиеся файлы u-boot-x96maxplus.bin и u-boot-x96max.bin, как наиболее подходящие по имени приставки. Забегая вперед, скажу, что это подходящие файлы. Любой из них можно использовать для загрузки этой приставки. Я пробовал подключать различные DTB файлы. Но система в сети не появлялась. Попытки тыкаться носом как слепой котенок начинали казаться тупиковыми. Нужно было увидеть логи чтобы выявить в чем о��ибка.
Вообще, эти эксперименты я начал еще год назад и подопытная приставка была довольно сложным кейсом за счет огромного количества отличающихся ревизий с новым оборудованием и отсутствующими открытыми драйверами. Тогда она еще не поддерживалась в Armbian и приходилось мудрить. Cо многими другими приставками дела обстояли несколько проще. Если вам тупо установить Linux и не вникать во внутренности загрузчика и ядра, то стоит выбрать нечто более обкатанное вроде приставок на процессоре Amlogic S905X2. В таком случае вы можете просто скачать готовый образ системы и сделать все по инструкции, а мой пост вам даже не понадобится. Пошаговых инструкций в интернете миллион. Впрочем, сейчас моя приставка уже поддерживается и, скорее всего, со всеми приведенными граблями вы не столкнетесь. Но мой опыт вполне может пригодиться.
Подключение UART консоли

Чтобы выяснить суть проблемы и увидеть логи нужно подключиться к консоли через предусмотренный для этого UART интерфейс. Для этого понадобится UART USB адаптер и паяльник, чтобы подпаять три проводка: RX (receive), TX (transmit), GND. Мой адаптер CH340G позволяет переключать уровень сигнала между 3.3в. или 5в. Но подойдет любой другой на 3.3в. Соединять нужно перекрестно: RX приставки на TX адаптера и TX приставки на RX адаптера. Контакт 3.3в. не подключаем никуда. После подключения адаптера на десктопном Linux должно появиться устройство /dev/ttyUSB0, которое говорит, что адаптер распознался и готов к использованию.
picocom -b 115200 -r -l /dev/ttyUSB0

Как только включим питание приставки, окно picocom должно показать логи загрузки системы. Тут всё нужно внимательно прочесть и выявить ошибки. Усложняется все тем, что большинство ошибок являются нормой, так как скрипты прорабатывают различные варианты загрузки и вываливают всю информацию по этому поводу.
Еще очень полезно подключить UART консоль тем, кто хочет попасть в шел-консоль Android. На моей прошивке не понадобился ни логин ни пароль: сразу после загрузки я мог писать команды.
console:/ $ uname -a Linux localhost 4.9.113 #3 SMP PREEMPT Fri Apr 15 18:28:24 CST 2022 armv7l console:/ $ lsmod lsmod Module Size Used by sdio_bt 20480 0 vlsicomm 1576960 0 aml_sdio 28672 2 sdio_bt,vlsicomm galcore 372736 0 aml_hardware_dmx 135168 0 amvdec_mavs 40960 0 vpu 45056 0 encoder 49152 0 amvdec_avs2 192512 0 amvdec_vp9 110592 0 amvdec_vc1 57344 0 amvdec_real 40960 0 amvdec_mmpeg4 40960 0 amvdec_mpeg4 57344 0 amvdec_mmpeg12 40960 0 amvdec_mpeg12 102400 0 amvdec_mmjpeg 28672 0 amvdec_mjpeg 40960 0 amvdec_h265 135168 0 amvdec_h264mvc 53248 0 amvdec_mh264 155648 0 amvdec_h264 135168 0 amvdec_avs 65536 0 stream_input 159744 12 aml_hardware_dmx,amvdec_mavs,amvdec_avs2,amvdec_vp9,amvdec_real,amvdec_mmpeg12,amvdec_mpeg12,amvdec_h265,amvdec_h264mvc,amvdec_mh264,amvdec_h264,amvdec_avs decoder_common 172032 18 amvdec_mavs,encoder,amvdec_avs2,amvdec_vp9,amvdec_vc1,amvdec_real,amvdec_mmpeg4,amvdec_mpeg4,amvdec_mmpeg12,amvdec_mpeg12,amvdec_mmjpeg,amvdec_mjpeg,amvdec_h265,amvdec_h264mvc,amvdec_mh264,amvdec_h264,amvdec_avs,stream_input firmware 24576 19 amvdec_mavs,encoder,amvdec_avs2,amvdec_vp9,amvdec_vc1,amvdec_real,amvdec_mmpeg4,amvdec_mpeg4,amvdec_mmpeg12,amvdec_mpeg12,amvdec_mmjpeg,amvdec_mjpeg,amvdec_h265,amvdec_h264mvc,amvdec_mh264,amvdec_h264,amvdec_avs,stream_input,decoder_common media_clock 36864 14 aml_hardware_dmx,amvdec_mavs,vpu,encoder,amvdec_avs2,amvdec_vp9,amvdec_mpeg12,amvdec_h265,amvdec_mh264,amvdec_h264,amvdec_avs,stream_input,decoder_common,firmware tb_detect 20480 0 atbm8881_fe_32 122880 0 mali_kbase 471040 11
При попытке загрузки с флэшки мне эта консоль навалила огромную кучу текста, которая сначала ошарашила. Но, покопавшись некоторое время, я понял суть первой проблемы: флэшка не загрузочная лишь потому, что она тупо не совместима с загрузчиком. Позже я выяснил, что с сменой флэшки на более другую (брэнд не имеет значения) можно перейти к решению последующих проблем, одной из которых являл��я неработающий сетевой адаптер. Но к этому я пришел позже. А пока я хотел понять, что дает самостоятельная сборка Armbian, какие проблемы можно с ее помощью решить.
Получение исходников Armbian и компиляция
Сборка Armbian невероятно просто и надежно сделана. Никакой установки стороннего софта мне делать не пришлось потому что все собирается в контейнере-песочнице, скачивая все необходимые зависимости. Сборку я делал в системе Gentoo, где отсутствуют такие команды как apt или deb, используемые в большинстве скриптов для установки. Главное выделить под эту вакханалию по меньшей мере 35 гигабайт места.

git clone https://github.com/armbian/build cd build /compile.sh EXPERT="yes"
Параметр EXPERT="yes" нужен чтобы нам, как экспертам, открылись недоступные для нубов экспериментальные платформы. Я выбрал aml-s9xx-box. Дальше выбираем по очереди:
"Do not change the kernel configuration" выбрать не грешно если вы не настоящий эксперт. А настоящий эксперт на этом этапе сможет к примеру включить дополнительные драйвера в компилируемом ядре.
aml-s9xx-box - выбираем если у вас процессор Amlogic s905x3 как у меня, иначе разбирайтесь какая платформа вам подойдет.
current или edge (latest). Я остановился на current чтобы выбрать не самые экспериментальные базовые системы. Но это совсем не значит, что этим выбором можно защититься от неприятностей, которые вас давно ждут, как только вы назвались экспертом.
Выбираем базовую ОС.
У меня заработала только Ubuntu Jammy 22.04 LTS. Заставить kde-plasma нормально работать в Debian 11 и 12 у меня не получилось как я ее не пытался удалять и ставить заново через apt (о подобных неприятностях я и говорил).Desktop Environment.
Я выбрал kde-plasma. И да, использование kde-plasma на приставке - это ошибка (тормозит жутко).config-base - лишь одна опция
Выбираете нужный вам софт

Дальше идет процесс компиляции, повторить который можно не проходя заново все этапы через меню. Меню конфигурации лишь сформировало вот такую команду, запуск которой нам соберет образ для загрузочного носителя:
./compile.sh build BOARD=aml-s9xx-box BRANCH=current BUILD_DESKTOP=yes BUILD_MINIMAL=no DESKTOP_APPGROUPS_SELECTED='3dsupport browsers' DESKTOP_ENVIRONMENT=kde-plasma DESKTOP_ENVIRONMENT_CONFIG_NAME=config_base EXPERT=yes KERNEL_CONFIGURE=no RELEASE=jammy
К сожалению, компиляция не решила проблем неработоспособности сетевого интерфейса eth0, но в будущем позволила опробовать различные версии различных дистрибутивов Debian и Ubuntu в то время как выбор готовых сборок очень ограничен. Если вас не толкают возникшие трудности на эксперименты как меня, смело пропускайте самостоятельную сборку. Одной из таких трудностей для меня оказалась установка kde-plasma через apt. Понятия не имею, почему такое происходит, но заметил, что иногда программы, скомпилированные локально через сборщик работают корректно, а установленные через apt глючат. Конкретно, в KDE не отображались иконки и меню.
Запись образа на носитель
Если ошибок при компиляции не было, то в директории ./output/images/ загрузочный образ диска будет ждать записи на носитель. Используйте Rufus или Balena Etcher для записи образа на флэшку, а я сделаю старым дедовским методом:
dd if=output/images/Armbian_23.08.0_amlogic_s905x3_lunar_6.1.55_server_2023.10.02.img of=/dev/sde bs=1M
В качестве загрузочного носителя можно использовать как USB флэшку, так и MicroSD карточку. Но, имейте ввиду, что загрузчик может закапризничать независимо от брендовости. Так у меня он отказался работать с MicroSD Samsung на 32Гб. и Transcend 16Гб., но заработал с древней ноунейм карточкой 16Гб. с надписью Taiwan и с обычной древней USB флэшкой Transcend 8Гб. Выглядят эти ошибки вот так:
emmc/sd response crc error, cmd16, cmd->cmdarg=0x200, status=0x1ff2400 ** Unrecognized filesystem type **
Правки полученного носителя
Этот этап для меня был самым сложным и занял больше всего времени. По сути на этом этапе вы находитесь будто в самом начале поста скачали готовый образ носителя. Мне же чтобы добиться работоспособности пришлось вникнуть в суть происходящих процессов, о которых я вам и поведаю.
Дело в том, что эта инструкция - хак. Никакой загрузки другой операционной системы с флэшки в ТВ приставке, конечно же, не предусмотрено, как и официальных альтернативных систем кроме Android от поставщика. Но есть возможность обновления с внешнего носителя. Такой носитель нам и нужно сделать, а потом перейти в режим разработчика или зубочисткой заставить плату загрузиться с него.
Основная проблема заключается в том, что приставки даже на одном и том же процессоре могут отличаться без предупреждений производителей (ведь одинаковые модели производят в разных китайских подвалах, как мы догадываемся). Заменят микросхему сети Realtek на Ampak или решат не паять внешний PHY, в свою прошивку внесут изменения в драйверах, но акцентировать внимание на этом не будут. А это нужно знать чтобы выбрать подходящий загрузчик и настроить эти устройства.
Итак, для корректной загрузки нам нужно найти подходящий для нашей платформы загрузчик u-boot и, специфический для ARM платформы, файл DTB (device tree blob).
Усложняется ситуация тем, что на приставке название пишется не полное. Например, на моей написано X96 Max+. А вот, чтобы выяснить что она "100W" пришлось потрудиться. Ведь именно у этой модели на борту микросхема радиомодуля, отвечающего за BT и Wifi малораспространенная W522A. Можно взять прошивку от похожей платы, но радиомодуль там работать не будет. Впрочем, как спойлер, скажу что у меня в Armbian он так и не заработал.
Во встраиваемых системах на ARM для того чтобы инициализировать устройства платы, которые не могут быть определены автоматически, используют Device Tree структуры. К таким устройствам относятся процессор, память. В исходных файлах Device Tree Source (DTS) текстом описываются устройства, частоты, адреса. Эти человекочитаемые файлы компилируются в бинарные DTB (Device Tree Blob), которые уже понимает ядро Linux. Чтобы не утонуть в дебрях деревьев устройств нам нужно просто подобрать подходящие к нашей плате DTB файлы. Откройте на полученной после записи образа флэшке раздел armbi_boot. В директории ./dtb/amlogic есть коллекция файлов, из которых нам нужно выбрать подходящий к нашей плате. Казалось бы, берем meson-sm1-h96-max.dtb или meson-g12a-x96-max.dtb и вписываем в ./extlinux/extlinux.conf . Но не тут-то было! Ни с одним из них не работает сеть:
root@aml-s9xx-box:/home/oper# ifconfig eth0 192.168.1.4/24 SIOCSIFFLAGS: Connection timed out
Если без wifi/BT я еще готов мириться, то вот без ethernet мне этот микрокомпьютер совсем не годится. Коллекция DTB файлов лежит на флэшке в разделе armbi_boot в директории ./dtb/amlogic.
Почитав форумы Armbian, все у кого такая приставка, как у меня X96 Max Plus 100W использовали файл meson-sm1-x96-max-plus-100m.dtb. Но у меня и с ним сеть не заработала. А весь секрет оказался в том, что у них на приставке была запаяна микросхема PHY для гигабитной сети, фото которой я показал в самом начале. Мне же понадобится встроенная в SOC подсистема, которая называется RMII и есть файл DTB, который ее поддерживает: meson-g12a-x96-max-rmii.dtb. Вот это и есть тот файл DTB, который позволил мне использовать eth0 в Armbian. Выяснить эту проблему и проблему с несовместимой флэшкой без UART консоли было бы невозможно.
Уроки u-boot
Пришло время рассказать, как я выяснил что флэшка просто несовместима с загрузчиком. Решение простое, но чтобы его увидеть мне пришлось потратить кучу времени и разобраться с загрузчиком u-boot, скриптами загрузки и с теми сообщениями что он мне вываливал. Всё как в байке про специалиста, который брал 1$ за удар молотком и 999$ за то, что знал куда ударить. Делюсь рецептом как выяснять куда нужно ударить.
Нажимаем в консоли сразу после включения много раз Ctrl+C и попадаем в командную строку загрузчика u-boot. Это совсем не Linux, но работать в нем с периферийными устройствами придется. И чтобы вы могли докопаться до сути в случае проблемы с загрузкой покажу несколько приемов для затравки.
Команда help напишет вам список поддерживаемых команд. Из этих команд можно составлять скрипты, которые несколько напоминают bash.
g12a_u212_v1#help ? - alias for 'help' aml_sysrecovery- Burning with amlogic format package from partition sysrecovery amlmmc - AMLMMC sub system amlnf - aml mtd nand sub-system autoscr - run script from memory avb - avb base - print or set address offset bcb - bcb bmp - manipulate BMP image data boot_cooling- cpu temp-system booti - boot arm64 Linux Image image from memory bootm - boot application image from memory bootp - boot image via network using BOOTP/TFTP protocol cbusreg - cbus register read/write chpart - change active partition clkmsr - Amlogic measure clock cmp - memory compare cp - memory copy crc32 - checksum calculation cvbs - CVBS sub-system dcache - enable or disable data cache defenv_reserv- reserve some specified envs after defaulting env dhcp - boot image via network using DHCP/TFTP protocol dovi - Dolby_vision sub-system dtimg - manipulate dtb/dtbo Android image echo - echo args to console efuse - efuse commands efuse_user- efuse user space read write ops emmc - EMMC sub system env - environment handling commands ethloop - ethloop - loopback test using ethernet test package exit - exit script ext4load- load binary file from a Ext4 filesystem ext4ls - list files in a directory (default /) ext4size- determine a file's size false - do nothing, unsuccessfully fastboot- use USB Fastboot protocol fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) fatsize - determine a file's size fdt - flattened device tree utility commands forceupdate- forceupdate get_avb_mode- get_avb_mode get_bootloaderversion- print bootloader version get_rebootmode- get reboot mode get_system_as_root_mode- get_system_as_root_mode get_valid_slot- get_valid_slot go - start application at address 'addr' gpio - query and control gpio pins gpt - GUID Partition Table guid - GUID - generate Globally Unique Identifier based on random UUID hdmitx - HDMITX sub-system 20190123 help - print command description/usage i2c - I2C sub-system icache - enable or disable instruction cache img_osd - image osd sub-system imgread - Read the image from internal flash with actual size itest - return true/false on integer compare jtagoff - disable jtag jtagon - enable jtag keyman - Unify key ops interfaces based dts cfg keyunify- key unify sub-system ld_bl40 - load bl40 and run bl40.bin from bl33 loadb - load binary file over serial line (kermit mode) loadx - load binary file over serial line (xmodem mode) loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range macreg - ethernet mac register read/write/dump md - memory display mm - memory modify (auto-incrementing address) mmc - MMC sub system mmcinfo - display MMC info mtdparts- define flash/nand partitions mw - memory write (fill) mwm - mw mask function nand - NAND sub-system nboot - boot from NAND device nm - memory modify (constant address) open_scp_log- print SCP messgage osd - osd sub-system phyreg - ethernet phy register read/write/dump ping - send ICMP ECHO_REQUEST to network host printenv- print environment variables query - SoC query commands rarpboot- boot image via network using RARP/TFTP protocol readMetadata- readMetadata read_temp- cpu temp-system reboot - set reboot mode and reboot system reset - Perform RESET of the CPU ringmsr - Amlogic measure ring rpmb_state- RPMB sub-system rsvmem - reserve memory run - run commands in an environment variable saradc - saradc sub-system saradc_12bit- saradc sub-system saveenv - save environment variables to persistent storage sdc_burn- Burning with amlogic format package in sdmmc sdc_update- Burning a partition with image file in sdmmc card set_active_slot- set_active_slot set_trim_base- cpu temp-system set_usb_boot- set usb boot mode setenv - set environment variables sf - SPI flash sub-system showvar - print local hushshell variables sleep - delay execution for some time sspi - SPI utility command store - STORE sub-system systemoff- system off tee_log_level- update tee log level temp_triming- cpu temp-system test - minimal test like /bin/sh tftpboot- boot image via network using TFTP protocol true - do nothing, successfully ubi - ubi commands ubifsload- load file from an UBIFS filesystem ubifsls - list files in a directory ubifsmount- mount UBIFS volume ubifsumount- unmount UBIFS volume ui - ui sub-system unpackimg- un pack logo image into pictures update - Enter v2 usbburning mode usb - USB sub-system usb_burn- Burning with amlogic format package in usb usb_update- Burning a partition with image file in usb host usbboot - boot from USB device uuid - UUID - generate random Universally Unique Identifier version - print monitor, compiler and linker version viu_probe- enable viu probe in no secure chip vout - VOUT sub-system vout2 - VOUT2 sub-system vpp - vpp sub-system vpu - vpu sub-system write_trim- cpu temp-system write_version- cpu temp-system
Кроме команд в u-boot очень важно понимать суть переменных.
setenv - создает, переопределяет или стирает переменную если значение не указано.
Примеры.
Установить 'a' равной '123':
setenv a 123
Стереть переменную 'a'
setenv a
Напечатать значение 'a'
printenv a
После манипуляций с переменными можно сохранить значения чтобы после перезагрузки они не забылись командой save или saveenv.
Загрузка с внешнего носителя начинается со скрипта в корневой директории первого раздела (armbi_boot) этого носителя в файле aml_autoscript. Это бинарный файл, который напрямую не стоит редактировать, хотя код при открытии этого файла можно разобрать в текстовом виде. Начинается код так:
if printenv bootfromsd; then exit; else setenv ab 0; fi;
Одной из важных переменных, которая используется многими скриптами является 'bootfromsd'. Не поверите, но чтобы загрузиться с внешнего носителя эта переменная должна быть стерта как мы видим из этого кода. Вы можете взять куски кода из этого скрипта и проверить в командной строке u-boot. Но чтобы проверить эти куски кода, нужно понять еще несколько моментов, которые умеет u-boot.
Подсистема usb позволяет работать с USB флэшкой:
usb start - инициализировать подсистему
Вставьте флэшку и введите:
fatls usb 0 - показать файлы на USB устройстве с индексом 0.
Эта команда работает как с FAT, так и с EXT4 разделами. Так что можно не беспокоиться о том, что BOOT раздел Armbian хранится в ext4. Дальше считаем файл boot.scr в область памяти по адресу 0x1000000:
g12a_u212_v1# fatload usb 0 0x1000000 boot.scr reading boot.scr 8147 bytes read in 27 ms (293.9 KiB/s)
Дальше запустим загруженный скрипт командой autoscr:
autoscr 0x1000000
Аналогично можно работать с подсистемой mmc только для ее инциализации нужно запускать команду
mmc rescan
В общем, суть всех скриптов u-boot попробовать инициализировать очередную подсистему и загрузить какой-либо файл, а дальше действовать в зависимости от результата этих действий и выставленных переменных.
После усвоения вышеприведенной информации есть смысл заглянуть в следующую переменную среды u-boot, которая содержат сценарий загрузки с карточки:
recovery_from_sdcard=if fatload mmc 0 ${loadaddr} aml_autoscript; then autoscr ${loadaddr}; fi;if fatload mmc 0 ${loadaddr} recovery.img; then if fatload mmc 0 ${dtb_mem_addr} dtb.img; then echo sd dtb.img loaded; fi;wipeisb; setenv bootargs ${bootargs} ${fs_type};bootm ${loadaddr};fi;
Этот скрипт пытается загрузить с mmc под индексом 0 файл aml_autoscript и запустить его. В случае неудачи пытается загрузить recovery.img и dtb.img, и если они загрузились, сообщает об этом, модифицирует переменную bootargs и загружает приложение по адресу загрузки командой bootm. Этот скрипт, сохраненный в переменную recovery_from_sdcard можно запустить следующей командой:
run recovery_from_sdcard
Именно этот скрипт и используется для запуска нашей системы с SD карты. Если что-то во время загрузки пошло не так, проверьте все шаги из командной строки u-boot.
Когда я запортачил загрузку, убив систему на EMMC, я тупо переопределил эту переменную:
setenv recovery_from_sdcard 'usb start;fatload usb 0 0x1000000 u-boot.ext;go 0x1000000'
Проверить что все сохранилось:
g12a_u212_v1#printenv recovery_from_sdcard recovery_from_sdcard=usb start;fatload usb 0 0x1000000 u-boot.ext;go 0x1000000
Дальше надо сохранить эти настройки (вы ведь сохранили себе предыдущее значение чтобы вернуть как было когда надоест!?) Но тут и вылезла еще одна моя проблема:
g12a_u212_v1#saveenv Saving Environment to aml-storage... get partition info failed !!
Мой u-boot не умеет работать с EMMC. На этом этапе костыли начинают надоедать. Хочется сесть, досканально разобраться в этом вопросе и написать нормальный загрузчик для приставки. Но пока я лишь в начале пути.
А теперь вишенка на торте - из u-boot можно запустить другой u-boot тремя шагами загрузив в память и запустив бинарный код по адресу командой go. Вот так выглядит запуск u-boot из файла u-boot-x96maxplus.bin:
usb start fatload usb 0 0x1000000 u-boot-x96maxplus.bin g12a_u212_v1#go 0x1000000 ## Starting application at 0x01000000 ... U-Boot 2021.07-rc3-00183-gd6e1cdad51-dirty (May 31 2021 - 22:33:28 +0800) x96-max-plus Model: AMedia X96 Max+ SoC: Amlogic Meson SM1 (Unknown) Revision 2b:b (1:2) DRAM: 3.8 GiB MMC: sd@ffe03000: 0, sd@ffe05000: 1, mmc@ffe07000: 2 Loading Environment from nowhere... OK In: serial Out: serial Err: serial Net: eth0: ethernet@ff3f0000 Hit any key to stop autoboot: 0 starting USB... Bus usb@ff500000: Register 3000140 NbrPorts 3 Starting the controller USB XHCI 1.10 scanning bus usb@ff500000 for devices... 2 USB Device(s) found scanning usb for storage devices... 1 Storage Device(s) found Device 0: Vendor: JetFlash Rev: 1100 Prod: Transcend 8GB Type: Removable Hard Disk Capacity: 7722.0 MB = 7.5 GB (15814656 x 512) ... is now current device Scanning usb 0:1... Found /extlinux/extlinux.conf Retrieving file: /extlinux/extlinux.conf 577 bytes read in 12 ms (46.9 KiB/s) 1: Armbian Retrieving file: /uInitrd 23401755 bytes read in 966 ms (23.1 MiB/s) Retrieving file: /Image 27363840 bytes read in 1133 ms (23 MiB/s) append: root=UUID=1fa9b58c-1f95-468b-868f-6dbc919d31f3 rootflags=data=writeback console=ttyAML0,115200n8 console=tty0 rw no_console_suspend consoleblank=0 fsck.fix=yes fsck.repair=yes net.ifnames=0 splash plymouth.ignore-serial-consoles Retrieving file: /dtb/amlogic/meson-g12a-x96-max-rmii.dtb 74923 bytes read in 16 ms (4.5 MiB/s) Moving Image from 0x8080000 to 0x8200000, end=9cb0000 ## Loading init Ramdisk from Legacy Image at 13000000 ... Image Name: uInitrd Image Type: AArch64 Linux RAMDisk Image (gzip compressed) Data Size: 23401691 Bytes = 22.3 MiB Load Address: 00000000 Entry Point: 00000000 Verifying Checksum ... OK ## Flattened Device Tree blob at 08008000 Booting using the fdt blob at 0x8008000 Loading Ramdisk to 3e9ae000, end 3ffff4db ... OK Loading Device Tree to 000000003e998000, end 000000003e9ad4aa ... OK Starting kernel ... ...
Так, если не получается найт годный u-boot с поддержкой EMMC, то можно решить проблему в лоб и работать только с флэшки с тем бутом, который есть. Для этого создаем на компьютере файл aml_autoscript.cmd с содержимым:
usb start fatload usb 0 0x1000000 u-boot.ext go 0x1000000
Для загрузки с MMC карты код должен выглядеть так:
mmc rescan fatload mmc 0 0x1000000 u-boot.ext go 0x1000000
Конечно же вместо u-boot.ext нужно подставить имя файла загрузчика с вашей флэшки или переименовать его в u-boot.ext . Компилируем aml_autoscript.cmd в бинарь и кладем полученый aml_autoscript на флэшку в бут раздел:
mkimage -C none -A arm -T script -d aml_autoscript.cmd aml_autoscript
mkimage - это программа из пакета u-boot-tools.
На этом этапе нужно убедиться что в файле extlinux/extlinux.conf прописан верно подходящий FDT. Если extlinux.conf по этому адресу переименован в extlinux.conf.bak, то изменять FDT уже нужно в файле uEnv.txt (для Armbian 6).
Запуск
Как я говорил, загрузка с флэшки включается зубочисткой, но есть другой вариант.
Вставить внешний носитель с системой, загрузиться в Android и переключаемся в режим разработчика. Для этого заходим в настройки, выбираем информацию о версии и кликаем по ней пять раз. Должно появиться сообщение о том что режим активирован.
Установить adb (обычно пакет android-tools-adb) и запустив по сети две команды IP адреса вашей приставки через сеть:
adb connect x.x.x.x adb shell reboot update
В итоге система загружается. Если были выбраны дисплейный менеджер и среда рабочего стола, то она загрузится и попросит пароль. Первоначальный пароль системы Armbian root:1234, но меня система заставила создать всех пользователей с паролями при первой заг��узке. Использовать как десктопный компьютер телевизионную приставку - идея не из лучших не смотря на то, что сейчас даже драйвер Panfrost, имплементирующий OpenGL для ARM, уже встроен в систему. В лучшем случае, как тонкий клиент. Youtube показывает видео без тормозов, но сама система по отзывчивости оставляет желать лучшего. Возможно, использование быстрых носителей исправит ситуацию, но у меня с этим какая-то беда и невезение.
Резюме
Итак, подводя итог для установки Armbian на TV-box нам достаточно лишь подготовить загрузочный носитель и заставить приставку загрузиться с него:
скачать образ системы Armbian;
записать образ на USB флэшку или карточку памяти;
прописать DTB файлы в ./extlinux/extlinux.conf или uEnv.txt в зависимости от версии Armbian
переименовать выбранный файл u-boot именно от этой платы загрузчика в u-boot.ext;
прописать файл с настройками сети /etc/network/interfaces.d/eth0;
переключиться в режим обновления с нашего носителя одним из двух способов: режим разработчика или зубочисткой;
загрузиться, убедиться что устройство появилось в сети и приступить к настройке;
Ссылки
Репозиторий Armbian:
https://github.com/armbian/build
Труды по запуску Armbian на ТВ-приставках самых различных моделей:
https://github.com/ophub/amlogic-s9xxx-armbian
Некоторые пояснения ситации на github по поводу приставки X96 Max Plus 100W:
https://github.com/ophub/amlogic-s9xxx-armbian/issues/909
Раскирпичивание приставки X96 Max Plus после порчи EMMC системы через замыкание boot контакта на плате:
https://www.youtube.com/watch?v=3do6lDOj2LU
