Mini2440 – Emulando Atari com Linux embarcado

- por Sergio Prado

Categorias: Linux, Mini2440 Tags: ,

Nesta nossa área cheia de novidades e desafios constantes, fica difícil acompanhar tudo o que acontece sem realmente gostar e se divertir com o trabalho. Sempre que eu preciso encarar um novo desafio (seja pessoal ou profissional), é aí que busco minhas forças. Paixão pelo trabalho é fundamental para manter a disciplina e buscar aquela energia extra que realmente faz a diferença.

E seguindo esta filosofia de “aprendizado com diversão”, pensei no que ainda poderia explorar no kit FriendlyARM mini2440, que não tivesse sido feito, e que fosse desafiador, estimulante e divertido.

Tive então a idéia de emular o Atari 2600. Sim, aquele console antigo, mas que (pelo menos para mim) traz boas lembranças dos tempos de infância. Minha idéia foi transformar a mini2440 em um console Atari 2600, usando um display LCD de 3.5″ como saída de vídeo, um joystick USB como controle e um cartão SD para ler as ROMs (jogos).


Escolhi usar o Stella (http://stella.sourceforge.net/), um emulador de Atari multi-plataforma e liberado sob a licença GPL. Meu primeiro passo foi dar uma olhada nos pré-requisitos do projeto, que basicamente são estes:

  • Requisitos de Hardware
    • 32M de RAM: OK, o kit tem 64M.
    • Display gráfico de 16 bits: o display é de 3.5″ e suporta modo gráfico de 16 bits.
    • Entrada para joystick: temos a porta USB.
    • Arquitetura i386, MIPS, PPC: Ops, nada de ARM? Será que funciona?
  • Requisitos de software:
    • Linux 2.6: OK!
    • GNU C++ 4.x: precisaremos habilitar a toolchain C++ no Buildroot.
    • SDL V1.2.10 ou maior: precisaremos habilitar o SDL no Buildroot.

Não me parecia nada de outro mundo. Escolhi o Buildroot como sistema de build para gerar minha imagem final. Bastaria seguir este meu artigo, configurar e adicionar o pacote do Stella, e habilitar algumas opções adicionais, como toolchain C++ e a biblioteca SDL.

NEM TUDO SÃO ROSAS

Pois é, nem tudo são rosas. O que achei que levaria uma tarde me tomou muito mais tempo. Nada funcionou de primeira. Quer uma lista de alguns desafios que encontrei?

1. O vídeo não renderizava em modo paisagem. O driver de framebuffer do display LCD suportava apenas 240×320, enquanto que o Stella roda apenas com resoluções a partir de 320×240. Depois de dias debugando e estudando o driver do display, a biblioteca SDL e a aplicação Stella, encontrei uma solução bem simples: setar uma variável de ambiente usada pela biblioteca SDL para rotacionar o display! Sim, foram dias de análise para resolver o problema com uma linha de código em shell script! Mas no fim, adquiri bastante conhecimento na camada de vídeo do Linux.

$ export SDL_VIDEO_FBCON_ROTATION=CW

2. Com a correção da renderização do vídeo, causei um problema com o touchscreen. Como eu rotacionei o display, os valores lidos pelo touch ficaram deslocados. Precisei escrever um patch que fizesse esse hack na biblioteca SDL.

--- sdl-1.2.14-orig/src/video/fbcon/SDL_fbevents.c  2009-10-12 20:07:15.000000000 -0300
+++ sdl-1.2.14/src/video/fbcon/SDL_fbevents.c   2011-04-23 16:20:31.623212774 -0300
@@ -741,11 +741,14 @@
 static void handle_tslib(_THIS)
 {
    struct ts_sample sample;
-   int button;
+   int button, aux;
 
    while (ts_read(ts_dev, &sample, 1) > 0) {
        button = (sample.pressure > 0) ? 1 : 0;
        button <<= 2;   /* must report it as button 3 */
+       aux = 240 - sample.x;
+       sample.x = sample.y;
+       sample.y = aux;
        FB_vgamousecallback(button, 0, sample.x, sample.y);
    }
    return;

3. Também tive problemas com o som, que não funcionava com o driver padrão em modo OSS. Resolvi o problema habilitando o biblioteca ALSA no Buildroot, e criando alguns links simbólicos para os arquivos de dispositivo do driver de som.

Package Selection for the target
    Audio and video libraries and applications
        [*] alsa-lib
$ mkdir -p /dev/snd/
$ ln -s /dev/pcmC0D0c  /dev/snd/pcmC0D0c
$ ln -s /dev/pcmC0D0p  /dev/snd/pcmC0D0p
$ ln -s /dev/controlC0 /dev/snd/controlC0
$ ln -s /dev/timer     /dev/snd/timer
$ chmod 0660 /dev/pcmC0D0c
$ chmod 0660 /dev/pcmC0D0p
$ chmod 0660 /dev/controlC0
$ chmod 0660 /dev/timer

Para testar o som com a biblioteca ALSA:

$ aplay /usr/share/sounds/alsa/Front_Center.wav

4. O joystick funcionou de primeira, mas estranhamente causava erro de segmentação de memória na aplicação Stella ao tentar usar o direcional. Então descobri que precisava habilitar a interface de joystick no kernel.

Device Drivers
    Input device support
        [*] Joystick interface
        [*] Joysticks/Gamepads
            [*] Classic PC analog joysticks and gamepads

5. Além disso, enfrentei alguns pequenos desafios como colocar o pacote Stella no Buildroot (desenvolvi um patch para corrigir um erro de cross-compilação). Também precisei habilitar e configurar o hotplug no kernel o mdev no Buildroot para identificar e montar automaticamente o cartão SD no boot.

Realmente foi um projeto que deu trabalho, mas é o tipo de experiência que vale a pena, pois é um aprendizado não se consegue apenas lendo livros ou artigos na internet.

No final, criei um script para facilitar todo o processo para quem também quiser “brincar”. Disponibilizei este script, junto com todos os arquivos necessários para compilar e gerar a imagem, em um projeto no github, que pode ser acessado aqui.

GERANDO A IMAGEM

Para gerar a imagem, execute os comandos abaixo:

$ git clone git://github.com/sergioprado/Mini2440-Atari-System.git
$ cd Mini2440-Atari-System
$ ./prepare.sh
$ cd buildroot-2011.02/
$ make

O processo de compilação deve levar de 1 a 2 horas, dependendo da sua máquina. Após compilar, você terá disponível em output/images as imagens do kernel e do rootfs disponíveis:

$ ls output/images/
rootfs.ext2  rootfs.jffs2  rootfs.tar  uImage

Para gravar o kernel e o rootfs, você pode se basear neste artigo aqui. Mude apenas a configuração da variável “bootargs” do U-Boot, conforme abaixo:

MINI2440 # setenv bootargs 'root=/dev/mtdblock3 rootfstype=jffs2 console=ttySAC0,115200 mini2440=3tb'
MINI2440 # saveenv

TESTANDO

No primeiro boot, você precisará configurar a interface touchscreen, pressionando a caneta nos pontos indicados pela ferramenta de configuração. Após configurar o touchscreen, a aplicação Stella já inicia automaticamente, e você poderá configurar seu joystick em “Options->Input Settings” se quiser.

Depois, escolha um jogo e divirta-se! Estes são os meus favoritos:


Obs: Não quero entrar aqui nos méritos legais de usar um emulador com ROMs. Apenas para constar, você precisa ter o jogo para poder baixar a ROM e usá-la em um emulador.

Gravei também um vídeo onde podemos ver o boot da mini2440 e alguns jogos em ação. Só não reclamem das habilidades do jogador! Coloquei minha esposa para jogar enquanto gravava. O problema foi tirar o controle dela depois… :)


E para concluir, o que podemos tirar de aprendizado neste projeto?

Primeiramente, se você quer aprender, precisa colocar a mão na massa! Só assim para transformar seu conhecimento em habilidades. Com um pouco de criatividade, disciplina e persistência, você consegue aprender coisas que talvez não aprenderia em um emprego formal.

Em segundo lugar, perceba a importância do código livre para este projeto. Tudo o que fiz foi usando software e ferramentas de código aberto. Ter em mãos o código do kernel do Linux e das bibliotecas foi essencial para solucionar alguns dos problemas que encontrei no meio do caminho. Escrevendo este artigo, disponibilizando o projeto e motivando as pessoas a fazerem o mesmo, espero estar contribuindo de volta com a comunidade.

Um abraço!

Sergio Prado

Faça um Comentário

Navegue
Creative Commons Este trabalho de Sergio Prado é licenciado pelo
Creative Commons BY-NC-SA 3.0.