Последовательный порт UART в ТВ-боксах


  Монтаж       Проблемы       Прошивка     Варианты     Log U-Boot     Help U-Boot  


2. Проблемы и их решение


В нормальной ситуации мы должны увидеть в окне терминала сначала лог запуска загрузчиков, затем запуск U-Boot и переход его в командный режим нажатием любой кнопки на клавиатуре ПК (удобнее на Пробел - он большой), а при пропуске этого сообщения (Hit any key) переход к загрузке системы (несколько сообщений в логе), которая заканчивается переходом в консольный режим линукса и полной остановкой вывода сообщений.

И вот тут нас постигнет неудача:

  • 1. Переход в командный режим U-Boot невозможен, ни на какие кнопки реакции нет, вместо этого продолжается загрузка системы.
  • 2. Переход в консоль после загрузки ядра также невозможен из-за непрерывного и бесконечного потока сообщений, которые сыпятся в терминал.

    Вопрос: за что боролись ? И к чему тогда все эти пляски с проводами и переходниками...

    Ладно, придется искать причины этих неприятностей. Для этого посмотрим на структуру разделов, который создаются в памяти устройства. И на их содержимое.

    И нужный нам раздел нашёлся: маленький, но гордый и важный. Размер раздела всего 16 Mb, при этом в него записывается целиком файл размером 130 Кб, в котором значащих данных всего примерно 5 Кбайт, остальное - пустое место.

    Он потому и сделан как отдельный раздел, что в нем хранится информация, необходимая для правильной работы загрузчика U-Boot.

    Итак, мы смотрим раздел Env. Его название - не что иное, как сокращение от слова Environment, что означает "окружение" или "cреда". Это защищенное хранилище переменых среды (или переменных окружения), которыми пользуется загрузчик U-Boot, копируя эти переменные в оперативную память и выполняя записанные в этих переменных команды и настраивая систему. Переменные среды в исходном виде представляют собой массив обычных текстовых строк, разделенных нулевыми байтами. В таком виде они хранятся в файле env.fex, входящем в состав образа прошивки, в таком же виде они записываются в одноименный раздел env в хранилище устройства.

    В таблице разделов GPT раздел ENV описан так:

    • Partition Type GUID (GUID типа раздела) = ebd0a0a2-b9e5-4433-780c-68b6b72699c7
    • Unique Partition GUID (GUID раздела) = 0a805564-1466-47a4-a353fca9272b8e46
    • Starting LBA 98304 (N блока первого сектора раздела) = 0x3000000
    • Ending LBA 131071 (N блока последнего сектора раздела) = 0x4000000
    • Attributes ( атрибуты раздела) = 0000000000020008 [0]
    • Partition Name (имя раздела) = env
    • Partition Size (размер раздела): блоков = 32768 (0x8000), 16 Мбайт
    • Время создания раздела 27.03.2020 15:17:10

    В этот раздел ENV при установке прошивки на устройство записывается содержимое файла env.fex, имеющегося в образе прошивки XXX.img. Этот файл можно извлечь из образа утилитой imgrepacker.exe, запустив её в окне консоли (или в командной строке) Windows.

    Кроме того, его можно скопировать командой dd непосредственно из памяти устройства, сохранив в файл:


    dd if=/dev/block/mmcblk0p2 of=/mnt/media_rw/681F-F2F4/env.img bs=512 count=256
    здесь media_rw/681F-F2F4 - это USB-флешка, в результате получим файл размером 131072 байта.

    Анализ содержимого файла env.fex показывает, что в нем содержится 26 строк:


    • 1) earlyprintk=sunxi-uart,0x05000000
    • 2) initcall_debug=0
    • 3) console=ttyS0,115200
    • 4) nand_root=/dev/nand0p4
    • 5) mmc_root=/dev/mmcblk0p4
    • 6) init=/init
    • 7) loglevel=8
    • 8) selinux=0
    • 9) cma=64M
    • 10) mac=
    • 11) wifi_mac=
    • 12) bt_mac=
    • 13) specialstr=
    • 14) hx_flag=
    • 15) keybox_list=hdcpkey,widevine
    • 16) setargs_nand=setenv bootargs earlyprintk= initcall_debug= console= loglevel= root= init= partitions= cma= snum= mac_addr= wifi_mac= bt_mac= selinux= specialstr= hx_flag= gpt=1
    • 17) setargs_mmc=setenv bootargs earlyprintk= initcall_debug= console= loglevel= root= rootwait init= partitions= cma= snum= mac_addr= wifi_mac= bt_mac= selinux= specialstr= hx_flag= gpt=1
    • 18) boot_normal=sunxi_flash read 45000000 boot;bootm 45000000
    • 19) boot_recovery=sunxi_flash read 45000000 recovery;bootm 45000000
    • 20) boot_fastboot=fastboot
    • 21) recovery_key_value_max=0x13
    • 22) recovery_key_value_min=0x10
    • 23) fastboot_key_value_max=0x8
    • 24) fastboot_key_value_min=0x2
    • 25) bootdelay=0
    • 26) bootcmd=run setargs_nand boot_normal

    Сейчас мы не будем исследовать смысл и назначение каждой строки. Нас интересут толко две из них, а именно 7-я и 25-я. Эти две строки - источник всех бед, описанных выше. Поэтому нужно внести в них исправления.

    Строка bootdelay=0 (ждать 0 секунд) сообщает загрузчику U-Boot, что он должен не ждать нажатия каких-либо кнопок (от слова - совсем), а сразу переходить к исполнению команд, содержащихся в переменной bootcmd, т.е. запускать загрузку ядра системы. Поэтому необходимо заменить 0 на любое не очень большое целое число, например сделать bootdelay=5.


    UPD:
    Примечание. Самое забавное, что в документации на U-Boot утверждается, что если переменная bootdelay=0, то U-Boot без таймаута проверяет нажатие клавиши на клавиатуре и переходит после этого в командный режим. Однако на практике этого не происходит, видимо в исходном тексте есть ошибка (надо бы проверить), поэтому по bootdelay=0 сразу идет продолжение загрузки. При этом в каком-то конфиге по дефолту этот параметр равен нулю, а сборщики образов прошивок не проверяют работу U-Boot. Поэтому на всех прошивках для Allwinner (проверял на Android 10 и Android 12) разных моделей приставок получаем один и тот же результат: U-Boot на стоковой прошивке на прием команд не работает (от слова 'совсем').

    С таким значением U-Boot будет обязан ждать 5 секунд, отображая обратный отсчет, как при запуске космической ракеты. И мы всегда успеем нажать на клавиатуре кнопку остановки (или просто будем держать клавишу пробела нажатым в момент подачи питания или рестарта).

    Пробел предпочтителен по двум причинам:

  • 1) кнопка большая, легче попасть в цейтноте
  • 2) никакой реакции U-Boot на неё не будет, а какая-то другая может быть воспринята как команда.

    Итак, с одной проблемой мы справились. Ура !

    Теперь переходим ко второй проблеме.

    Строка loglevel=N, где N - число от 1 до 8, устанавливает уровень важности выводимых в терминал сообщений: 1 - самые критичные ошибки, 2 - менее критичные и т.д., а 8 - вообще все сообщения, включая ошибки, предупреждения и прочий словесный мусор.

    В исходном файле переменных окружения установлено значение loglevel=8, поэтому этот спам обеспечен и он бесконечен.

    Ну вот, включаем антиспам и ставим значение loglevel=2. Теперь при нормальном включении и загрузке системы никаких лишних сообщений не будет или будут сообщения о фатальных или критических ошибках (а если что-то совсем пошло не так, то просто пойдет дым...).

    Но пока это всё теория, и возникает вопрос: как практически отредактировать этот файл и что с ним делать дальше.

    Для редактирования есть разные возможности.

    Например, использовать продвинутый HEX-редактор. Единственная с ним сложность: правильно вычислить контрольную сумму CRC32 и записать её в файл (это первые четыре байта в самом начале файла).

    Поэтому был написан простенький скрипт , который делает эту процедуру автоматически, быстро и надёжно.

    Для проверки правильности сделанных изменений достаточно сравнить исходный файл с изменённым с помощью консольной команды (мы используем Windows):

     fc /b env.fex env.img > diff.txt  

    здесь

  • env.fex - исходный файл env
  • env.img - отредактированый файл env
  • diff.txt - текстовый файл с найденными отличиями

    Отличаться должны 6 байтов: первые 4 - это контрольная сумма, и ещё два байта 38 -> 32 и 30 -> 35

    Например, так:

      00000000: F5 73
      00000001: 2B BB
      00000002: 97 CA
      00000003: 95 AE
      00000090: 38 32
      00000496: 30 35
    

    Ну хорошо, теперь у нас имеется откорректированный файл env.img. Что дальше ?

    Кстати, этот файл (для приставки Transpeed на H616) можно забрать по ссылке ниже. После скачивания извлечь из zip-архива файл env.img. Сравните его со своим указанной выше командой. Если отличия только в 6 байтах ( и 38->32, 30->35), то этим файлом можно воспользоватся в готовом виде.



    ВНИМАНИЕ. Для любой приставки на Allwinner H616 или H618 (а также, возможно, и для других брендов и моделей) файл переменных окружения можно исправить с помощью специального онлайн-сервиса:
    Конвертор файла переменных окружения ENV .

    Для получения такого откорректированного файла в качестве исходного (загружаемого по upload) файла можно использовать либо файл env.fex, извлеченный из образа прошивки, либо файл dd-бекапа раздела env (или env_a,env_b (первых 256 Kbyte).




    *************************

    Дополнение.


    Удалось обнаружить ещё один способ входа в оболочку U-Boot - с помощью ИК-пульта.
    Единственное условие: пульт должен иметь адрес FE01 (это пульты от Transpeed и некоторых других приставок).

    Если в терминале по UART не удается войти в командную оболочку U-Boot из-за установленного значения bootdelay=0, то можно поробовать сделать это с ИК-пульта. Последовательность действий:

  • подключиться к UART и запустить сеанс терминала в MobaXTerm на ПК

  • взять в руки ИК-пульт

  • подать питание на приставку, при этом несколько раз нажать на кнопку пульта MENU (с полосочками) (или HOME-домик или BACK-назад)

  • загрузчи U_BOOT автоматически выполнит команду sprite_test, после чего он останется в командной оболочке с приглашением '='>
    bar x1: 320 y1: 320
    bar x2: 960 y2: 400
    357443 bytes read in 16 ms (21.3 MiB/s)
    [SFTE_Set_Pixel_Sizes_i] 394 buf_size is 2304
    cur_pixel_size 32 pixel_size 32
    sunxi sprite begin
    =>
    

  • при этом на экране монитора отобразится контур красного прямоугольника - это видимый результат теста. Теперь можно пользоваться командами U-Boot. Но нужно учитывать, что в таком состоянии в переменных ENV, загруженных в память, изменено значение bootcmd, поэтому командой boot для продолжения загрузки пользоваться нельзя.

    ВНИМАНИЕ !. Нельзя также пользоваться командой ENV SAVE или SAVEENV, т.к. это приведет к сохранению в разделе ENV модифицированной переменной bootcmd и при следующем включенни (даже без пульта) произойдет точно такая же загрузка в тест и командную оболочку.

    Поэтому после внесения необходимых изменений в ENV перед его сохранением (если очень нужно и есть понимание последствий) нужно восстановить значение переменной bootcmd, выполнив команду:

     env set bootcmd run setargs_mmc boot_normal