Peguei uma das TV boxes para experimentar; detalho aqui meus resultados, tentativas e tribulações:
Especificações
- Nome de mercado: MXQ Pro 5G 4K
- SoC: Rockchip RK322x (provavelmente RK3229)
- RAM: 1GB[1]
- Flash: 8GB, NAND Micron controlada via software[2]
Objetivos
- Executar uma distribuição Linux de forma aceitável[3]
UART
A placa possui pads expostos conectados a uma interface UART, rotulados R, T e G e configurados para 1500000 baud durante a inicialização da placa (embora alguns pacotes, notavelmente o multitool, reconfigurem a interface para o mais comum 115200 baud durante o processo de boot). Headers foram soldados a um dos exemplares para simplificar o acesso a interface:
Software existente
Armbian
“Meta-distribuição” Linux oferecendo imagens baseadas em Debian e Ubuntu para diversas placas ARM, juntamente a um sistema de build altamente flexível. O projeto fornece imagens pré-compiladas para placas RK322x utilizadas em TV boxes. As imagens, tanto pré-compiladas quanto geradas a partir do sistema de build do projeto aparentam não possuir bootloader instalado da forma esperada pela placa (ver Processo de boot).
Multitool
Utilitário para manutenção e instalação de imagens desenvolvido pelo autor do port do Armbian para a placa, comunmente referenciado em tutoriais durante o processo de instalação. Tanto a imagem disponibilizada no tópico oficial do port quanto a compilada pelo autor do artigo aparentam funcionar conforme esperado no equipamento em questão. O script de build fornece um exemplo prático de como se empacotar uma imagem de sistema operacional para a placa, utilizando o idbloader proprietário da Rockchip.
Processo de boot
O conteudo a seguir ainda não é completamente entendido pelo autor, e pode não representar de fato o que ocorre durante o processo. Caveat emptor.
O processo de boot para os SoCs da Rockchip é documentado em https://opensource.rock-chips.com/wiki_Boot_option.
Existem dois métodos de inicialização oficialmente suportados para placas baseadas no RK3229, um utilizando o idbloader/miniloader proprietário da Rockchip, e outro utilizando o TPL/SPL do projeto U-Boot, completamente(?) software livre. Em ambos os casos o processo culmina na execução do U-Boot, comum em placas ARM de natureza similar, que fica responsável por carregar o kernel e passar o controle para o sistema operacional conforme apropriado.
Para ser selecionado[4] como dispositivo de boot, nosso cartão SD precisa que alguns componentes do metodo de inicialização selecionado estejam presentes em endereços pré determinados.
TODO: Escrever sobre os componentes do processo de boot, seus endereços e função durante a inicialização; exemplos de como preparar uma imagem para boot com ambos os métodos, assim que entender melhor como as coisas se encaixam.
Recursos, materiais e referências
- CSC Armbian for RK322x TV box boards - Armbian Community Forums: Tópico oficial do port do Armbian para TV boxes utilizando SoCs RK322x; inclui informações relevantes sobre o estado do Linux e do Armbian nessas placas, peculiaridades de hardware notáveis e informações para instalação e depuração da mesma, juntamente informações sobre o multitool, desenvolvido pelo autor do tópico.
Status atual, e coisas a se fazer
Por agora, estou tentando:
- Entender o processo de boot
- Coagir alguma distribuição Linux a inicializar pelo cartão SD
- Utilizando o idbloader
- Utilizando o TPL/SPL do U-Boot
Para reempacotar a imagem do Armbian com o bootloader do minitool, tentei a seguinte sequencia de comandos:
Comandos utilizados
# I'm assuming
# - an armbian image at `armbian-latest.img'
# - a checkout of multitool's repository at `multitool/'
# - you are running as root (prefix sudo/doas/whatever as appropriate)
# create our target image
truncate -s 1280M repack.img
# and a few temporary directories
mkdir -p tmp mnt/boot
# set up loopback devices
# - for the source image
source=$(losetup -Pf --show armbian-latest.img)
# - for our target
target=$(losetup -Pf --show repack.img)
# set up the partition table. we'll be creating
# - a FAT32 partition to hold u-boot's Extboot bootmeth configuration,
# sized 64M and starting at fdisk's default 2048th sector (enough to
# hold idbloader et al. behind it)
# - a Linux partition spanning the rest of the image
fdisk $target <<-EOF
o
n
+64M
t
0b
a
n
w
EOF
boot=${target}p1
root=${target}p2
source_root=${source}p1
# copy over the rootfs
pv $source_root | dd of=$root bs=64k
# set up the u-boot configuration
# for more information, see https://docs.u-boot.org/en/latest/develop/bootstd/overview.html
mkfs.vfat $boot
mount $boot mnt/boot
boot_uuid=$(blkid -o value -s PARTUUID $boot)
root_uuid=$(blkid -o value -s PARTUUID $root)
mkdir mnt/boot/extlinux
cat <<-EOF | tee mnt/boot/extlinux/extlinux.conf
LABEL Armbian
LINUX /kernel.img
FDT /rk322x-box.dtb
APPEND boot=UUID=$boot_uuid root=PARTUUID=$root_uuid rootwait console=ttyS2,115200 verbose=1 consoleblank=0
EOF
# copy over the kernel and device tree from multitool
# TODO test with Armbian's kernel instead
board=multitool/sources/rk322x
cp $board/{kernel.img,rk322x-box.dtb} mnt/boot
umount mnt/boot
# install rockchip's idbloader
tools=multitool/tools
# pack uboot
$tools/loaderimage \
--pack --uboot $board/u-boot-dtb.bin \
tmp/uboot.img \
0x61000000
# TODO ^ where does this address come from?
# pack trustos
$tools/loaderimage \
--pack --trustos $board/rk3228_tee_ta-51.1.0-333-gc9d95d1.bin \
tmp/trustos.img \
0x68400000
# TODO ^ ditto
# install (see https://opensource.rock-chips.com/wiki_Boot_option for more details):
# - uboot at 0x4000
dd if=tmp/uboot.img of=$target seek=$((0x4000))
# - tee at 0x6000
dd if=tmp/trustos.img of=$target seek=$((0x6000))
# - idbloader at 0x40
dd if=$board/idbloader_ddr_1.11.img of=$target seek=$((0x40))
# clean up after ourselves
losetup -d $source $target
rm -rf tmp
rmdir mnt/* mnt
O resultado carrega a imagem do U-Boot empacotada com sucesso, mas falha ao carregar o kernel, proseguindo para a tentativa de boot via rede.
Os passos foram derivados do script de compilação do multitool, simplesmente por imaginar que seria mais simples seguir um exemplo funcional. Alguns dos componentes presentes aparentam provenir do repositório de binários da Rockchip, outros (como a imagem do U-Boot utilizada, ou a device tree) são de provenância desconhecida. Não esperava um boot bem-sucedido a partir dessa tentativa, embora eu esperasse que pelo menos o kernel fosse carregado com sucesso.
Não quero seguir o procedimento de instalação para NAND pelo multitool por agora pois não tenho certeza do processo de recuperação, e quero eventualmente utilizar o kernel mainline, de qualquer forma.
É interessante notar que o dispositivo vem juntamente a uma etiqueta indicando que o mesmo haveria 3GB de RAM, e 4GB de flash interno, o que seria improvável, pois, assim como apontado pela datasheet do SoC, o mesmo só conseguiria endereçar até 2GB de memória. ↩︎
Os chips NAND não possuem controlador, sendo conectados direto no SoC. O fork do kernel da Rockchip possui um módulo específico para se comunicar com os chips. Até a data atual, o kernel mainline não possui driver para acessar o armazenamento interno da placa. ↩︎
Com “aceitável” sendo definido de forma parcialmente subjetiva :); ter as placas funcionando aceitavelmente como servidores seria conveniente; ter as placas funcionando aceitavelmente como terminais seria particularmente interessante. ↩︎
Por quem? A BootRom? O bootloader instalado na NAND? ↩︎