Mini2440 – Linux com U-Boot e Emdebian
- por Sergio Prado
No último artigo vimos com mais detalhes a arquitetura do kit FriendlyARM mini2440 e o bootloader que vem instalado de fábrica. Quem ainda não leu este post, pode acessá-lo aqui.
Vamos agora colocar a mão na massa. Nosso objetivo aqui é carregar na flash NAND o bootloader U-Boot, bastante usado em sistemas embarcados, e depois fazê-lo carregar uma imagem do Emdebian, uma versão do Debian mais leve.
O único pré-requisito é um kit FriendlyARM mini2440 conectado à uma máquina Linux pela serial (para acessar a console), pela USB (para transferir a imagem do U-boot) e por um cabo de rede (para carregar as imagens do kernel e do rootfs do Emdebian).
Usei o binário do U-boot deste link aqui. O kernel eu baixei daqui, mas precisei customizá-lo para habilitar o suporte à sistema de arquivos JFFS2 e corrigir o mapeamento das partições da MTD no driver da Flash. O rootfs eu peguei aqui (link não está mais disponível), mas também precisei “dar um tapa”, e corrigir um problema que impedia de subir o terminal pela console RS232.
Para facilitar o trabalho daqueles que irão executar este passo-a-passo, criei um “pacote especial” com todas as ferramentas e imagens necessárias para dar vida ao Emdebian no mini2440. Este pacote pode ser baixado aqui (infelizmente o link não está mais disponível). Descompacte-o para sua máquina e mãos à obra!
Bootloader U-Boot
O bootloader é uma aplicação que é carregada e executada assim que o hardware é ligado. No universo desktop, estamos familiarizados com o LILO ou o GRUB para carregar sistemas Unix-like, mas no universo embedded as coisas são um pouco mais complicadas. Um bootloader para sistemas embarcados possui 3 principais responsabilidades:
- Inicializar o hardware.
- Possibilitar a carga e gravação da aplicação na flash via alguma interface de I/O, como porta serial, USB ou interface de rede.
- Carregar e executar aplicações da RAM.
Um bootloader bem conhecido no universo embedded é o Das U-Boot, também conhecido apenas como U-Boot, um bootloader multi-plataforma e open-source, com suporte à diversas arquiteturas como PowerPC, ARM, MIPS, Coldfire e x86. A página do projeto pode ser acessada aqui.
O U-Boot será o bootloader que utilizaremos para carregar o Emdebian pela NAND. O processo para carregar e gravar o U-Boot na flash é simples.
Primeiro iremos carregar a imagem do U-Boot na RAM. Para isso precisaremos da imagem do U-Boot (“u-boot-256M.bin” ou “u-boot-128M.bin”, dependendo do seu kit), e da ferramenta “usbpush”. Todos os arquivos encontram-se no link que passei no início deste post. Não esqueça também que a serial e a USB devem estar conectadas.
Inicie o kit pela NOR, no menu do supervivi selecione a opção “q” e prepare-o para receber a imagem do U-Boot e salvar em RAM:
[q] Goto shell of vivi Enter your selection: q Supervivi> load ram 0x31000000 242360 u |
Obs: O parâmetro “242360” deve ser o tamanho em bytes da imagem do U-Boot (“u-boot-256M.bin” para a flash de 256M no meu caso).
Então, em um shell do Linux, digite o comando abaixo:
$ sudo ./usbpush u-boot-256M.bin |
A console irá exibir uma mensagem indicando que a transferência foi realizada com sucesso.
Agora iremos executar o U-Boot da RAM mesmo, assim podemos formatar a NAND e depois copiar o U-Boot para lá.
Digite então na console do mini2440:
Supervivi> go 0x31000000 |
Após algumas mensagens, irá aparecer o shell do U-Boot. Agora vamos formatar a flash. A execução dos comandos abaixo podem demorar um pouco, portanto tenha paciência :)
MINI2440 # nand scrub .... MINI2440 # nand createbbt .... |
Depois é só escrever o U-Boot na flash Nand.
MINI2440 # nand write.e 0x31000000 0 242360 |
Obs: Não se esqueça de que novamente o parâmetro “242360” deve ser o tamanho em bytes da imagem do U-Boot.
Muito bem. Você acabou de instalar o U-Boot na sua flash NAND. Desligue a placa, mude a chave para bootar pela NAND para a console cair no shell do U-Boot.
Este bootloader tem bastante recursos. O comando “help” vai exibir uma lista. Podemos por exemplo listar informações da placa ou das partições da flash, conforme abaixo:
MINI2440 # bdinfo arch_number = 0x000007CF env_t = 0x00000000 boot_params = 0x30000100 DRAM bank = 0x00000000 -> start = 0x30000000 -> size = 0x04000000 ethaddr = 08:08:11:18:12:27 ip_addr = 10.0.0.111 baudrate = 115200 bps MINI2440 # mtdparts device nand0 , # parts = 4 #: name size offset mask_flags 0: u-boot 0x00040000 0x00000000 0 1: env 0x00020000 0x00040000 0 2: kernel 0x00500000 0x00060000 0 3: root 0x0faa0000 0x00560000 0 active partition: nand0,0 - (u-boot) 0x00040000 @ 0x00000000 |
Podemos carregar uma aplicação via serial com os comandos “loadb”, “loads” e “loady”, via NFS com o comando “nfs”, via TFTP com o comando “tftpboot” ou via USB com o comando “usbboot”. Podemos também testar a RAM com os comandos “mtest” e “mw”.
Carregando o Emdebian
O Emdebian é uma versão do Debian para sistemas embarcados. Mantém as principais características do Debian, como sistema de gerenciamento de pacotes, sistema de licenças e portabilidade entre diversas plataformas. O sistema de build é customizado para trabalhar com pacotes pequenos e gerar distribuições bem mais leves. A página do projeto pode ser acessada aqui.
A carga do kernel (“uImage”) e do rootfs (“emdebian-jffs2.img“) é feita através de uma conexão de rede. Ligue seu PC com o mini2440 através de um cabo de rede, configure o endereço IP do seu PC com 10.0.0.1, e o do kit com 10.0.0.2. Configure o mini2440 através dos comandos abaixo na console do U-Boot:
MINI2440 # dynenv set 40000 MINI2440 # setenv ipaddr 10.0.0.2 MINI2440 # setenv serverip 10.0.0.1 MINI2440 # saveenv |
Use o comando “ping 10.0.0.1” na console do U-Boot para verificar se a conexão com o PC está funcionando corretamente.
Vamos agora gravar o kernel. O processo consiste em carregar a imagem do kernel para a RAM, e então de lá gravar na flash:
MINI2440 # tftp 0x31000000 uImage MINI2440 # nand erase kernel MINI2440 # nand write.e 0x31000000 kernel 0x205f58 |
Para o rootfs, o processo é idêntico:
MINI2440 # tftp 0x31000000 emdebian-jffs2.img MINI2440 # nand erase root MINI2440 # nand write.jffs2 0x31000000 root 0x23e0000 |
Agora só falta setar as variáveis de ambiente do U-Boot para iniciar o kernel do Linux corretamente:
MINI2440 # setenv bootcmd 'nboot.e kernel ; bootm' MINI2440 # setenv bootargs 'root=/dev/mtdblock3 rootfstype=jffs2 console=ttySAC0,115200' MINI2440 # saveenv MINI2440 # boot |
Pronto! O Emdebian já está rodando no nosso kit mini2440 (a senha padrão de root é “debian”):
Quando comecei a escrever este post, minha intenção original era carregar o Android, mas acabei “descobrindo” durante o processo que a quantidade de RAM do mini2440 (64M) não é suficiente para este SO. O que o pessoal acabou fazendo foi rodá-lo a partir de um cartão de memória SD usando um mecanismo de swap. Se isso funciona mesmo ou não, veremos no meu próximo post…:)
Um abraço!