Experimentações com a TV box MXQ Pro 5G 4K (RK322x)

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]
    • A partir de um cartão SD
    • A partir do flash interno
    • A partir da rede (i.e. PXE)
    • Com o kernel da Rockchip
    • Com um kernel mainline
      • Com aceleração 3D de hardware (via Lima)
      • Bonus: Com acesso ao flash interno
        • Com a raiz no flash interno

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.


  1. É 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. ↩︎

  2. 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. ↩︎

  3. 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. ↩︎

  4. Por quem? A BootRom? O bootloader instalado na NAND? ↩︎

1 Like