Попалась нам сегодня в руки отладочная плата на базе SoC RTD1185 — RTK300 Rev. C1 — для разработки мультимедийных устройств. В рамках этой статьи мы познакомимся с техническими параметрами этой SDK, cоберем и запустим на ней базовое ядро Linux и rootfs, успешно решив в процессе несколько проблем.
Disclaimer: данная статья рассчитана на опытных линуксоидов, по крайней мере, мы не останавливались на второстепенных подробностях. Если возникнут вопросы, добро пожаловать в комментарии.
Данная система на кристалле от наших друзей из Realtek c кодовым названием Jupiter, как и её брат RTD1186, предназначена для мультимедийных приложений, которые декодируют видео в форматах HD MPEG 1/2/4, H.264, VC1, RM/RMVB. Также в медиапроцессоре реализована поддержка разъемов USB 2.0 и SATA, шины PCI-Express и сетевого интерфейса Gigabit Ethernet.
Наличие Ethernet в связке с соответствующим сетевым контроллером обеспечивает возможность передачи данных по проводной сети со скоростью до 1 Гбит/с. Хоть данное устройство имеет по современным меркам небольшую частоту CPU, но этот параметр компенсируется мощными декодерами видео, что вполне оправдывает использование данного чипа в мультимедиа приложениях.
Технические параметры RTD1185:
- CPU: 500 МГц
- HD MPEG 1/2/4 & HD JPEG Decoder
- HD H.264, VC1, RM/RMVB, AVS Decoder
- TV Encoder with CVBS/S-Video/YPbPr/SCART Out
- HDMI v1.3 with CEC
- I2S, SPDIF Out
- USB2.0 Host & PHY
- USB2.0 Device & PHY
- SATA
- 10/100 Ethernet MAC & PHY
- Gigabit Ethernet MAC
- PCI-Express
- Card Reader (SD/MMC)
- DTV Recording & Time-Shifting
- Dual TS-In
Комплект Realtek RTL-1185
Плата идет в комплекте с ИК-пультом дистанционного управления. От Realtek был получен «полурабочий» SDK, который якобы должен был решить все проблемы со сборкой прошивки. «Полурабочим» мы его назвали потому, что у нас получилось собрать без «бубна» linux-2.6.12 и базовую rootfs. Но когда дело дошло до приложений аудио- и видеоплеера, пришлось все-таки взять «бубен». Ну что же, и на этом спасибо. Кит изображен на фотографии ниже.
На плате присутствуют следующие компоненты:
- SoC RTD11185
- 256MB RAM от NANYA
- 256MB NAND SLC — flash Samsung
- 2x 2.0 USB Host
- FastEthernet RJ45 розетка
- HDMI Transmitter out
- ИК-приемник для дистанционного управления (пульт имеется, фото ниже)
- Кнопка с фиксацией для включения/выключения
- В один USB Host вставлен USB WiFi на базе RTL8190U
- Штыревая вилка (UART)
- Кнопка восстановления
Работаем с китом
Ну что же, мы познакомились с платой, попробуем что-нибудь на ней запустить. Изначально на ките стояла прошивка Realtek, по всей видимости, она работала поверх QT4.7.
Когда мы получили этот SDK, казалось, что все — птица в кармане. Но не тут то было. Собирается, конечно, не все. Документации нет ни к отладочной плате, ни к самой системе на кристалле (SoC). Гугл тоже не помог. Но об этом далее.
В данной статье мы используем следующие обозначения:
- host# — команда выполняется на ArchLinux x86_64;
- ubuntu# — команда выполняется ubuntu-12.10 amd64 chroot;
- jupiter# — команда выполняется на ките;
Получаем консоль
С помощью осциллографа была выяснена распиновка UART на плате (возле кнопки восстановления): (USB HOST) GND – RX — TX — VCC.
Подключаемся с помощью minicom на хосте:
host$ minicom -D /dev/ttyUSB0 -c on
Включаем плату и нас встречает «приветливый» загрузчик:
hello_world!
5522880 0 wwaiaittcheck_val=0x2700a0
REALTEK ROM Monitor, Revision 0000.0311.0022-ON.
Copyright (c) Realtek Semiconductor Corp. - All Rights Reserved.
For a list of available commands, type 'help'.
Compilation time /version= Feb 4 2013 15:12:08 /0000.0311.0022-ON
MAC address = 00.11.22.33.44.55
Processor Company ID/options = 0x01 (MIPS Technologies, Inc.) / 0x00
Processor ID/revision = 0x93 / 0x78
Endianness = Little
Flash memory size = 256 MByte
SDRAM size = 256 MByte
First free SDRAM address = 0x800b1000
Press 'ESC' to Monitor mode
Linux Kernel:
FW Image from 0xa2020000, to 0x80100000, size=0x44f086
decrypt from 0xa2020000 to 0x80100000, len:0x44f086
Audio FW:
FW Image from 0xa2480000, to 0x81b00000, size=0x17b040
decrypt from 0xa2480000 to 0x81b00000, len:0x17b040
Video FW:
FW Image from 0xa2600000, to 0x81d80000, size=0x1bfd68
decrypt from 0xa2600000 to 0x81d80000, len:0x1bfd68
Audio data:
FW Image from 0xa27c0000, to 0x83000000, size=0x68c78
Video data:
FW Image from 0xa2840000, to 0x83100000, size=0x413428
5280Go 5280Go SCPU_CLK90K=0.000 sec.
Debug: [go 0x80100000 mtdparts=rtk_nand:212096k,3968k(/),32768k(/usr/local/etc),13312k rootfstype=squashfs root=31:01 ]
Reset Ethernet Mac.
Address = 0x80100000
После чего начинается загрузка ядра.
Что примечательно, firmware загружаются не драйвером в память, а самим загрузчиком.
Обновление прошивки
Ну что же, неплохо. Попытаемся обновить прошивку, которую в собранном виде была представлена в SDK.
- Для начала нужно отформатировать USB-накопитель:
host# mkfs.vfat /dev/sdx -n firmware
- Скопировать образ прошивки install.img на данный накопитель.
- Вставить флешку и запустить процесс обновления ПО. Запуск этого «процесса» можно осуществить 2-мя основными способами (существуют и другие):
- Recovery-режим загрузки: нужно включить плату с зажатой «кнопкой восстановления». Загрузчик при этом достает ядро по другому адресу во флеш, т.е., если при перепрошивке мы сделаем кирпич из нашей платы, зашив не то ядро, можно в любой момент загрузиться в Recovery-режиме.
- Стандартная загрузка: выбрать соответствующий пункт в GUI. Не будем подробно описывать этот вариант.
Все просто и понятно с первого взгляда. Форматируем. Копируем прошивку на флешку. Вставляем в устройство. Загружаемся в recovery-режиме. Флешка автоматически монтируется и начинается прошивка. За все это отвечает утилита loader_a. Но…
[MCP][RSA] strip rsa header failed - no rsa padding header detected
loader_a.c:verona_load_func:1456 Error! Image file, /mnt/usbmounts/sda/install.img, cannot be opened or the hash value is not correct.
+++ ALLOC index: 3072 order: 8
1. start remap DVR zone 81c00000(80409000) 256...
Ладно, что поделать. Пробуем по-другому.
Эту защиту можно обойти кривохаками, но нам пока это не нужно. Если кому-то интересно, то у утилиты прошивки loader_a есть аргумент — nonsecure который отключает проверку хэшем. Но для этого нужно собрать busybox для данной платформы и скопировать его тоже на USB-накопитель, загрузить плату в recovery-режиме и в shell'e линукс на ките выполнить:
jupiter# cp /mnt/usbmounts/sda1/busybox /tmp/busybox && chmod a+x /tmp/busybox && /tmp/busybox killall loader_a && rm /var/lock/hotplug/mount_tmp/.lock_sda && loader_a --nonsecure &
Busybox пришлось собирать, потому что в recovery initramfs нету ничего, чем можно было бы кильнуть процесс loader_a. Но это не основная причина. С ним было намного проще изучить внутренности recovery-режима, используя тот же ash, ls, cat из его состава, чем без них.
Собираем базовое ядро Linux и rootfs
Настало время собрать ядро и rootfs, используя SDK от Realtek. Так как мы работаем в ArchLinux x86_64, то обычно все операции по сборке embedded ПО осуществляем в Ubuntu 12.10 amd64 chroot по нескольким причинам:
- Часто все необходимые при сборке пакеты уже есть в Ubuntu.
- Embedded-разработчики консервативны, часто встречаются SDK в которых host-утилиты, необходимые для сборки прошивки (rootfs), собираются определенной старой версией gcc и библиотек, а так как у нас на арче постоянно свежая версия gcc, то часто возникают проблемы при сборке этих утилит. Намного проще развернуть chroot rootfs, чем возиться с поиском патчей или исправлять самостоятельно.
- Большинство SDK разворачиваются и тестируются как раз таки под Ubuntu. Дело даже не в самой Ubuntu. С таким же успехом можно развернуть у себя другой дистрибутив, если в этом возникает необходимость.
- Развертывание сборочной системы у заказчика происходит проще, так как можно передать ему всё вместе с chroot, и у него firmware соберется с большой вероятностью сразу. Но это в том случае, если заказчик не работает под Windows (в таком случае он будет использовать виртуальную машину и в этом смысла нету).
Ubuntu rootfs для chroot развертывается с помощью утилиты debootstrap, которую мы вытянули из AUR.
- развертываем ubuntu chroot wiki.ubuntu.com/DebootstrapChroot;
- монтируем proc, sysfs, devtmpfs, devpts для chroot;
- host# chroot ubuntu-12.10
- ubuntu# apt-get update
- ubuntu# apt-get install vim file lib32z1-dev libc6-i386 sed dos2unix python g++-4.4-multilib
- ubuntu# useradd -s /bin/sh -m developer
Сейчас копируем файлы SDK в ubuntu-12.10/home/developer/Jupiter.
- ubuntu# su developer /bin/bash
- ububtu$ cd /home/developer/Jupiter/linux/system
- ubuntu$ make menuconfig # включаем поддержку NFS и NFS root
- ubuntu$ make PRJ=develop.avhdd.jupiter.nand.loongtle
После данных операций получаем ядро и базовую rootfs.
Rootfs копируем в /srv/nfs/jupiter для того чтобы использовать nfs root. Добавляем /etc/exports соответствующие строки.
host# exportfs -a
Ядро копируем на tftp сервер в /srv/tftp/vmlinux.develop.avhdd.jupiter.nand.loongtle.bin.
Запускаем сервера tftp и nfs на хосте. Конфигурируем NIC хоста подключенный по ethernet к отладочной плате: Ipv4 192.168.0.1/24.
Запуск свежесобранного Linux
Перезагружаем плату и сразу же зажимаем ESC для того, чтобы перейти в monitor-режим:
REALTEK ROM Monitor, Revision 0000.0311.0022-ON.
Copyright (c) Realtek Semiconductor Corp. - All Rights Reserved.
For a list of available commands, type 'help'.
Compilation time /version= Feb 4 2013 15:12:08 /0000.0311.0022-ON
MAC address = 00.11.22.33.44.55
Processor Company ID/options = 0x01 (MIPS Technologies, Inc.) / 0x00
Processor ID/revision = 0x93 / 0x78
Endianness = Little
Flash memory size = 256 MByte
SDRAM size = 256 MByte
First free SDRAM address = 0x800b1000
Press 'ESC' to Monitor mode
Realtek> help
Available commands :
. . (repeat last command line)
; ; (command separator)
+ + <repeat count> ;
compare compare <address1> <address2> <size>
continue continue
copy copy [-f] <src> <dst> <size>
dump dump [-m][-8|-16|-32] <address> [<size>]
erase erase -e|-m| <address> <size>
factory factory [-r|-w|-sha1] <address> <size> or factory -c
fill fill [-8|-16|-32] <address> <size> <data>
fread fread tftp://<ipaddr>/<filename> <address>
fwrite fwrite tftp://<ipaddr>/<filename> <address> <size>
go go [?|.|<address> [<args>]]
help help [<command>]
info info [boot|board|cpu|sysctrl|memory|uart|all|pll]
keyset keyset
load load [-r]
([tftp:][//<ipaddr>][/<filename>]) |
([asc:] [//(tty0|tty1)])
ping ping ipaddr [<datagramsize>]
port port [-a] [-8|-16|-32] <address> [<value>]
reset reset
saveenv saveenv
setenv setenv [<variable> [<value>]]
stty stty [-tty<0|1>] [-b|-u|[-p][<baudrate>][n|o|e][7|8][1|2][hw|none]]
test test [-l] | [-m] [ <module> [ <module arguments> ] ]
Realtek>
Commandline загрузчика немного напоминает uboot, но это не он. Видно, что можно выгрузить файл по tftp, что мы и сделаем чтобы выгрузить ядро Linux из сети.
Realtek> fread tftp://192.168.0.1/vmlinux.develop.avhdd.jupiter.nand.loongtle.bin 0x80100000; go 0x80100000 root=/dev/nfs rw nfsroot=192.168.0.1:/srv/nfs/jupiter,v3
About to binary read tftp://192.168.0.1/vmlinux.develop.avhdd.jupiter.nand.loongtle.bin
.............................................................................................................................................................................................s
Address = 0x80100000
Realtek LINUX started...
Venus setting:
ROSs have 2621440 bytes RAM.
System CPU has 2 UARTs.
System CPU uses external timer interrupt.
Bootloader version: 0000.0311.0022-ON. This version string is of new format.
The information of this board: Company ID:0x0 CPU ID: 0x33 Board ID: 0x311
Ethernet Mac address: 00.11.22.33.44.55
Model Config length=0
Base year of RTC is 2010.
Config serial console: console=ttyS0,115200n8r
prom_flashsize = 0x10000000
…
BusyBox v1.1.3 (2014.01.27-13:35+0000) Built-in shell (ash)
Enter 'help' for a list of built-in commands.
/ # cat /proc/cpuinfo
system type : Realtek DMP/Jupiter
processor : 0
cpu model : MIPS 24K V7.8
BogoMIPS : 332.59
wait instruction : yes
microsecond timers : yes
tlb_entries : 32
extra interrupt vector : yes
hardware watchpoint : yes
ASEs implemented : mips16
VCED exceptions : not available
VCEI exceptions : not available
/ # cat /proc/fb
0 venusfb
/ # cat /proc/filesystems
nodev sysfs
nodev rootfs
nodev bdev
nodev proc
nodev sockfs
nodev usbfs
nodev pipefs
nodev futexfs
nodev tmpfs
nodev eventpollfs
nodev devpts
nodev ptpfs
ext3
squashfs
nodev dvrfs
nodev ramfs
vfat
nodev devfs
nodev nfs
nodev nfs4
nodev smbfs
nodev cifs
nodev jffs2
yaffs
yaffs2
nodev rpc_pipefs
/ # cat /proc/meminfo
MemTotal: 251716 kB
MemFree: 242036 kB
Buffers: 60 kB
Cached: 1372 kB
SwapCached: 0 kB
Active: 1144 kB
Inactive: 524 kB
HighTotal: 0 kB
HighFree: 0 kB
LowTotal: 251716 kB
LowFree: 242036 kB
SwapTotal: 32 kB
SwapFree: 32 kB
Dirty: 0 kB
Writeback: 0 kB
Mapped: 612 kB
Slab: 5496 kB
CommitLimit: 125888 kB
Committed_AS: 1588 kB
PageTables: 56 kB
VmallocTotal: 1048548 kB
VmallocUsed: 500 kB
VmallocChunk: 1047936 kB
Таким образом, мы получили базовую рабочую систему.
Что дальше?
Попытаться собрать QT, gstreamer. Найти и собрать в SDK или разработать cамостоятельно плагины для gstreamer для использования аппаратных декодеров. Возможно, придется избавиться от сборочной системы в SDK в пользу Buildroot. О чем еще, возможно, придется написать — шифрование ядра и firmware. Но это уже другая история для другой части статьи.
Спасибо за внимание!
Автор: Promwad