O objetivo deste artigo é compartilhar minha experiência na construção, a partir dos fontes, do sistema operacional para dispositivos móveis Android para a BeagleBone Black (BBB).
Acredito que ambos os componentes dispensam introduções e comentários. Mas, em todo caso, segue uma breve introdução: o Android é um sistema operacional de código aberto, criado e mantido pelo Google, para ser usado originalmente em dispositivos móveis como aparelhos celulares e tablets. A Beaglebone Black é uma placa do tipo ‘open source hardware’, desenvolvida por uma comunidade de projetistas de hardware com o objetivo de oferecer uma solução simples, de baixo custo e flexível para seus projetos. Inicialmente pensada como uma placa para projetos de eletrônica para hobbistas, esta placa se mostrou um computador embarcado de grande potencial e baixo custo, podendo ser aplicada em diversos projetos de sistemas embarcados.
Atualmente o uso do Android não se restringe a dispositivos móveis. Este sistema operacional tem sido usado para diversas outras aplicações. Entre suas vantagens, destaca-se:
- Plataforma de desenvolvimento de software bem definida e robusta, mantida pelo Google;
- Ambiente de desenvolvimento baseado na linguagem Java, que possui uma enorme massa crítica de desenvolvedores;
- Plataforma de código aberto facilita o acesso aos recursos e informações;
- Royalties Free – competitividade em custo do produto final.
Hoje vemos o Android operando em televisores, eletrodomésticos e equipamentos industriais específicos. Para aplicação nestes cenários, hardware dedicado é construído para estes projetos e, com isso, o sistema operacional deve ser adaptado para operar neste novo cenário.
A motivação deste artigo é apresentar, de forma resumida, como dar o pontapé inicial neste mundo, digamos, um pouco mais ‘baixo nível’.
Então vamos começar! Para compilar o Android, usou-se a versão Rowboat, específica para processadores da família Sitara, da Texas Instruments. Este guia é uma adaptação do material presente no próprio site do projeto e pretendo detalhar ou explicar melhor as instruções presentes naquele tutorial.
Pré-requisitos
Para compilar o Android, é mandatório se ter um sistema operacional 64bits!
No meu caso, eu usei o UBUNTU 12.04 LTS 64 BITS.
Outro requisito mandatório: JAVA 6 (JDK).
A última versão disponível para Java é a 7. Você deve entrar no site da Oracle e baixar a JDK correta, dentro da opção de ‘versões anteriores’. E, para a versão Linux, você não deve baixar o arquivo RPM. Você deve baixar o arquivo BIN.
Com sorte, este link irá direto para o download. Segue abaixo um simples procedimento para instalação:
cd /opt sudo wget https://download.oracle.com/otn/java/jdk/6u45-b06/jdk-6u45-linux-x64.bin sudo chmod a+x jdk-6u45-linux-x64.bin sudo ./jdk-6u45-linux-x64.bin <Processo de instalação> sudo rm jdk-6u45-linux-x64.bin export PATH=/opt/jdk1.6.0_45/bin:$PATH
Ao final deste processo, o Java estará instalado em /opt e a variável PATH estará pronta para executar esta versão do Java instalada. Vale lembrar que caso o computador seja reiniciado ou a janela de terminal fechar, a ultima instrução deverá ser executada novamente.
Uma vez instalado o Java, vamos instalar os pacotes necessários para realização da compilação.
sudo apt-get install minicom tftpd uboot-mkimage expect
Com estas configurações, podemos começar a compilar o Android.
Passo 1 – download dos fontes
O primeiro passo é construir a estrutura de diretórios:
cd mkdir bbb cd bbb mkdir bin mkdir rowboat-android
O diretorio bbb é o diretório principal do projeto.
O diretório bbb/bin é onde será instalado o utilitário repo.
O diretório bbb/rowboat-android é onde se encontram os arquivos de compilação do Android.
Uma vez construída a estrutura de diretório, vamos baixar e instalar o utilitário repo.
cd ~/bbb/bin curl https://commondatastorage.googleapis.com/git-repo-downloads/repo > ./repo
Repo é um utilitário construído para facilitar o uso do git para download de diversos repositórios diferentes, oriundo de diferentes fontes e de diferentes branches. Trata-se de um utilitário que talvez mereça um artigo específico sobre ele.
Com o repo devidamente instalado, vamos baixar os fontes do Android.
cd ~/bbb/rowboat-android ../bin/repo init -u git://gitorious.org/rowboat/manifest.git -m rowboat-jb-am335x.xml ../bin/repo sync
Agora é hora de relaxar, assistir aquele filme ou ler um livro ou navegar na internet. Esta etapa demora …. e muito.
Ao final desta execução, temos os seguintes componentes:
- Bootloader u-boot
- Kernel Linux
- Toolchain
- Fontes do Android (equivalente à distribuição ou root filesystem, em uma arquitetura Linux embarcado padrão)
Vale lembrar que o Rowboat é uma adaptação do Android para processadores da Texas Instruments. Em uma compilação padrão do Android, a partir de seus fontes, o bootloader e o kernel Linux são tratados separadamente.
Passo 2 – Compilação
De posse de todos os arquivos necessários, vamos compilar!
De acordo com as instruções do projeto, existem duas abordagem: a de compilar tudo (vencedora) e a de compilar por partes. Vou descrever separadamente e comentar cada uma das abordagens. Porém, a que eu realizei com sucesso foi a primeira.
Independente da forma a ser usada para compilar, o primeiro passo é deixar o toolchain disponível na variável PATH de seu terminal.
cd cd bbb/rowboat-android export PATH=$PWD/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin:$PATH
Passo 2.1 – Compilando tudo de uma só vez
Sem mais delongas, para compilar tudo de uma vez:
make TARGET_PRODUCT=beagleboneblack OMAPES=4.x
Outro momento de relaxamento. Este procedimento demora. Mas, ao final, teremos todos os componentes necessários.
Passo 2.2 – Compilação por componentes
A grande vantagem de compilar separadamente está no fato de que é possível realizar personalizações individuais em cada um dos componentes. Quando apenas um componente necessita de compilação, a reconstrução completa do sistema não é necessária e, com isso, a geração individual dos componentes se torna mais prática.
Os subitens a seguir descrevem como compilar os componentes elementares do Android.
Passo 2.2.1 – Bootloader
O bootloader usado para realizar o boot do Android é o u-boot, empregado em praticamente todos os sistemas embarcados baseados em processadores ARM.
Os comandos abaixo realizam a compilação do bootloader:
cd ~/bbb/rowboat-android/u-boot make CROSS_COMPILE=arm-eabi- distclean make CROSS_COMPILE=arm-eabi- am335x_evm_config make CROSS_COMPILE=arm-eabi-
A primeira chamada de make apaga toda compilação e configuração anterior que tenha sido feita anteriormente.
A segunda chamada de make configura os parâmetros do código fonte para compilação específica para a Beaglebone Black.
Por fim, a terceira chamada de make compila o projeto, gerando os binários necessários do bootloader.
Passo 2.2.2 – Kernel Linux
O Android utiliza como base o sistema operacional Linux. Na época do lançamento, o Android tinha patches específicos para atender às suas necessidades de funcionamento. A partir da versão 3.3 do kernel Linux, estes patches foram integrados ao mainline Linux. Desta forma, o kernel Linux presente neste projeto possui os patches desenvolvidos pela Texas Instruments e pela comunidade BeagleBoard de forma a funcionar de forma apropriada na BeagleBone Black.
O procedimento para compilação do kernel padrão é apresentado abaixo.
cd ~/bbb/rowboat-android/kernel make ARCH=arm CROSS_COMPILE=arm-eabi- distclean make ARCH=arm CROSS_COMPILE=arm-eabi- am335x_evm_android_defconfig make ARCH=arm CROSS_COMPILE=arm-eabi- uImage
A compilação do kernel Linux possui o mesmo conceito de compilação do U-boot. O primeiro make apaga qualquer vestígio de compilação e configuração anterior. O segundo make realiza a configuração específica para a Beaglebone Black. O terceiro make realiza a compilação e gera a imagem final de kernel Linux.
Passo 2.2.3 – Root filesystem
Para compilação da distribuição Android é feita através dos seguinte comandos:
cd ~/bbb/rowboat-android make TARGET_PRODUCT=beagleboneblack droid
Estes comandos compilam os componentes e controem o sistema de arquivos.
Para compilar as bibliotecas e drivers SGX para aceleração gráfica, devemos executar o seguinte comando:
cd ~/bbb/rowboat-android/hardware/ti/sgx make TARGET_PRODUCT=beagleboneblack OMAPES=4.x ANDROID_ROOT_DIR=~/bbb/rowboat-android make TARGET_PRODUCT=beagleboneblack OMAPES=4.x ANDROID_ROOT_DIR=~/bbb/rowboat-android install
Por fim, devemos criar um arquivo tarball para que uma imagem possa ser criada em um cartão SD. Para isso, este último comando deve ser executado:
make TARGET_PRODUCT=beagleboneblack fs_tarball
Ao final destas execuções, temos o sistema de arquivos pronto para geração da imagem no cartão SD.
Passo 3 – construção do cartão SD
Uma vez compilados todos os componentes do sistema, agora é a hora de gerar uma imagem para o cartão SD.
Este artigo descreve como construir um cartão SD para a Beaglebone Black. A transferência para o e-MMC presente na placa não será descrita neste documento. E precisamos de um cartão SD de pelo menos 4 GB de memória para a correta construção do sistema.
A construção do cartão SD é dividida em dois passos: consolidação dos arquivo e geração da imagem.
Passo 3.1 – Consolidação dos arquivos binários
Vamos criar um diretório específico para armazenar os binários gerados. Os comandos abaixo realizam este procedimento.
mkdir ~/bbb/rowboat-android/image_folder cd ~/bbb/rowboat-android/image_folder cp ../kernel/arch/arm/boot/uImage . cp ../u-boot/MLO . cp ../u-boot/u-boot.img . cp ../external/ti_android_utilities/ti_android_utilities/am335x/u-boot-env/uEnv_beagleboneblack.txt . cp ../out/target/product/beaglebone/rootfs.tar.bz2 . cp ../external/ti_android_utilities/am335x/mk-mmc/mkmmc-android.sh .
Os arquivos envolvidos neste diretório são os seguintes:
- uImage – imagem do Kernel Linux no formato suportado pelo U-boot
- MLO – bootstrapper. Primeiro binário a ser executado quando o processador é ativado
- u-boot.img – imagem do bootloader U-boot, chamado pelo MLO após ativação do processador
- uEnv_beagleboneblack.txt – arquivo com as variáveis de parâmetros lidas pelo U-boot ao iniciar o sistema operacional
- rootfs.tar.bz2 – sistema de arquivos com o Android
- mkmmc-android.sh – script que cria o cartão SD com a imagem do Android
Preparado o ambiente, vamos criar o cartão SD.
Passo 3.2 – Geração do cartão SD
Uma vez preparado o ambiente, a etapa final é construir o cartão SD propriamente dito.
O primeiro passo é adicionar o cartão SD no computador. O Ubuntu detecta automaticamente o cartão SD. Se ele não estiver vazio, ele deve montar as partições presentes no cartão SD. Isso significa que os drivers necessários para acesso deste cartão são ativados automaticamente (recurso conhecido como hotplugging). Este mapeamento implica em arquivos presentes no diretório /dev do sistema operacional.
Para descobrir qual é o arquivo correspondente ao sistema, executamos o seguinte comando:
dmesg
No meu caso, o cartão SD se encontra em /dev/sdb.
Por fim, executamos o script que gera o cartão SD.
cd ~/bbb/rowboat-android/image_folder sudo./mkmmc-android.sh /dev/sdb MLO u-boot.img uImage uEnv_beaglebone.txt rootfs.tar.bz2
Ao final do procedimento, o cartão estará pronto para uso.
Passo 4 – Boot da imagem
Agora que temos tudo pronto, vamos testar!
Para rodar o Android, é mandatório que a placa tenha uma fonte de energia que não seja o cabo USB. Para visualizar em um monitor, a CPU demanda energia. Recomendo que se use uma fonte de pelo menos 1.5 A.
Eu particularmente gosto de ver o boot pelo console. E, para isso, tenho meu cabo FTDI sempre à mão. Mas não é necessário, uma vez que sua CPU esteja ligado com um monitor no conector HDMI e um mouse no conector USB host.
Desligue sua Beaglebone Black da energia.
Conecte o cartão SD na placa.
Pressione o botão USER/BOOT.
Ligue a placa com o botão pressionado.
Na primeira vez leva um tempo a mais para se ter o Android surgindo na tela. Nas próximas será mais rápido.
Abaixo as mensagens de console do Android, vistas pelo cabo FTDI.
U-Boot SPL 2013.04-dirty (May 06 2013 - 16:12:47) musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, HB-ISO Rx, HB-ISO Tx, SoftConn) musb-hdrc: MHDRC RTL version 2.0 musb-hdrc: setup fifo_mode 4 musb-hdrc: 28/31 max ep, 16384/16384 memory USB Peripheral mode controller at 47401000 using PIO, IRQ 0 musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, HB-ISO Rx, HB-ISO Tx, SoftConn) musb-hdrc: MHDRC RTL version 2.0 musb-hdrc: setup fifo_mode 4 musb-hdrc: 28/31 max ep, 16384/16384 memory USB Host mode controller at 47401800 using PIO, IRQ 0 OMAP SD/MMC: 0 mmc_send_cmd : timeout: No status update reading u-boot.img reading u-boot.img U-Boot 2013.04-dirty (May 06 2013 - 16:12:47) I2C: ready DRAM: 512 MiB WARNING: Caches not enabled NAND: No NAND device found!!! 0 MiB MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1 *** Warning - readenv() failed, using default environment musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, HB-ISO Rx, HB-ISO Tx, SoftConn) musb-hdrc: MHDRC RTL version 2.0 musb-hdrc: setup fifo_mode 4 musb-hdrc: 28/31 max ep, 16384/16384 memory USB Peripheral mode controller at 47401000 using PIO, IRQ 0 musb-hdrc: ConfigData=0xde (UTMI-8, dyn FIFOs, HB-ISO Rx, HB-ISO Tx, SoftConn) musb-hdrc: MHDRC RTL version 2.0 musb-hdrc: setup fifo_mode 4 musb-hdrc: 28/31 max ep, 16384/16384 memory USB Host mode controller at 47401800 using PIO, IRQ 0 Net: <ethaddr> not set. Validating first E-fuse MAC cpsw, usb_ether Hit any key to stop autoboot: 0 gpio: pin 53 (gpio 53) value is 1 mmc0 is current device micro SD card found mmc0 is current device gpio: pin 54 (gpio 54) value is 1 SD/MMC found on device 0 reading uEnv.txt 214 bytes read in 4 ms (51.8 KiB/s) Loaded environment from uEnv.txt Importing environment from mmc ... Running uenvcmd ... reading uImage 4178672 bytes read in 504 ms (7.9 MiB/s) ## Booting kernel from Legacy Image at 81000000 ... Image Name: Linux-3.2.0-00245-g03f2a1e Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 4178608 Bytes = 4 MiB Load Address: 80008000 Entry Point: 80008000 Verifying Checksum ... OK Loading Kernel Image ... OK OK Starting kernel ... Uncompressing Linux... done, booting the kernel. [ 0.000000] Linux version 3.2.0-00245-g03f2a1e (phi_admin@Phi02) (gcc version 4.6.x-google 20120106 (prerelease) (GCC) ) #1 Tue Mar 18 15:46:42 BRT 2014 [ 0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c53c7d [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [ 0.000000] Machine: am335xevm [ 0.000000] Memory policy: ECC disabled, Data cache writeback [ 0.000000] AM335X ES2.0 (sgx neon ) [ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 130048 [ 0.000000] Kernel command line: console=ttyO0,115200n8 androidboot.console=ttyO0 mem=512M root=/dev/mmcblk0p2 rw rootfstype=ext4 rootwait init=/init ip=off [ 0.000000] PID hash table entries: 2048 (order: 1, 8192 bytes) [ 0.000000] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes) [ 0.000000] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes) [ 0.000000] Memory: 512MB = 512MB total [ 0.000000] Memory: 509880k/509880k available, 14408k reserved, 0K highmem [ 0.000000] Virtual kernel memory layout: [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB) [ 0.000000] fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB) [ 0.000000] vmalloc : 0xe0800000 - 0xff000000 ( 488 MB) [ 0.000000] lowmem : 0xc0000000 - 0xe0000000 ( 512 MB) [ 0.000000] modules : 0xbf000000 - 0xc0000000 ( 16 MB) [ 0.000000] .text : 0xc0008000 - 0xc078a000 (7688 kB) [ 0.000000] .init : 0xc078a000 - 0xc07e0000 ( 344 kB) [ 0.000000] .data : 0xc07e0000 - 0xc084ba70 ( 431 kB) [ 0.000000] .bss : 0xc084ba94 - 0xc09a3890 (1376 kB) [ 0.000000] NR_IRQS:396 [ 0.000000] IRQ: Found an INTC at 0xfa200000 (revision 5.0) with 128 interrupts [ 0.000000] Total of 128 interrupts on 1 active controller [ 0.000000] OMAP clockevent source: GPTIMER2 at 24000000 Hz [ 0.000000] OMAP clocksource: GPTIMER1 at 32768 Hz [ 0.000000] sched_clock: 32 bits at 32kHz, resolution 30517ns, wraps every 131071999ms [ 0.000000] Console: colour dummy device 80x30 [ 0.000183] Calibrating delay loop... 548.86 BogoMIPS (lpj=2744320) [ 0.048736] pid_max: default: 32768 minimum: 301 [ 0.048889] Security Framework initialized [ 0.048980] Mount-cache hash table entries: 512 [ 0.049468] CPU: Testing write buffer coherency: ok [ 0.049530] ftrace: allocating 22068 entries in 65 pages [ 0.132446] omap_hwmod: pruss: failed to hardreset [ 0.133392] print_constraints: dummy: [ 0.133636] NET: Registered protocol family 16 [ 0.134979] OMAP GPIO hardware version 0.1 [ 0.136291] omap_mux_init: Add partition: #1: core, flags: 0 [ 0.137634] omap_i2c.1: alias fck already exists [ 0.138275] omap2_mcspi.1: alias fck already exists [ 0.138397] omap2_mcspi.2: alias fck already exists [ 0.138580] edma.0: alias fck already exists [ 0.138610] edma.0: alias fck already exists [ 0.138641] edma.0: alias fck already exists [ 0.151519] bio: create slab <bio-0> at 0 [ 0.152679] SCSI subsystem initialized [ 0.153686] usbcore: registered new interface driver usbfs [ 0.153808] usbcore: registered new interface driver hub [ 0.153991] usbcore: registered new device driver usb [ 0.154357] registerd cppi-dma Intr @ IRQ 17 [ 0.154357] Cppi41 Init Done Qmgr-base(e087a000) dma-base(e0878000) [ 0.154388] Cppi41 Init Done [ 0.154418] musb-ti81xx musb-ti81xx: musb0, board_mode=0x13, plat_mode=0x3 [ 0.154602] musb-ti81xx musb-ti81xx: musb1, board_mode=0x13, plat_mode=0x1 [ 0.155151] omap_i2c omap_i2c.1: bus 1 rev2.4.0 at 100 kHz [ 0.156127] tps65910 1-002d: could not be detected [ 0.156768] Advanced Linux Sound Architecture Driver Version 1.0.24. [ 0.157440] Bluetooth: Core ver 2.16 [ 0.157531] NET: Registered protocol family 31 [ 0.157531] Bluetooth: HCI device and connection manager initialized [ 0.157562] Bluetooth: HCI socket layer initialized [ 0.157592] Bluetooth: L2CAP socket layer initialized [ 0.157623] Bluetooth: SCO socket layer initialized [ 0.157836] Switching to clocksource gp timer [ 0.180053] musb-hdrc: version 6.0, ?dma?, otg (peripheral+host) [ 0.180297] musb-hdrc musb-hdrc.0: dma type: dma-cppi41 [ 0.180511] MUSB0 controller's USBSS revision = 4ea20800 [ 0.180541] musb0: Enabled SW babble control [ 0.181579] musb-hdrc musb-hdrc.0: USB OTG mode controller at e083c000 using DMA, IRQ 18 [ 0.181854] musb-hdrc musb-hdrc.1: dma type: dma-cppi41 [ 0.182067] MUSB1 controller's USBSS revision = 4ea20800 [ 0.182098] musb1: Enabled SW babble control [ 0.182617] musb-hdrc musb-hdrc.1: MUSB HDRC host driver [ 0.182739] musb-hdrc musb-hdrc.1: new USB bus registered, assigned bus number 1 [ 0.182891] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002 [ 0.182922] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1 [ 0.182922] usb usb1: Product: MUSB HDRC host driver [ 0.182952] usb usb1: Manufacturer: Linux 3.2.0-00245-g03f2a1e musb-hcd [ 0.182952] usb usb1: SerialNumber: musb-hdrc.1 [ 0.183593] hub 1-0:1.0: USB hub found [ 0.183654] hub 1-0:1.0: 1 port detected [ 0.184112] musb-hdrc musb-hdrc.1: USB Host mode controller at e083e800 using DMA, IRQ 19 [ 0.184509] NET: Registered protocol family 2 [ 0.184753] IP route cache hash table entries: 4096 (order: 2, 16384 bytes) [ 0.185180] TCP established hash table entries: 16384 (order: 5, 131072 bytes) [ 0.185577] TCP bind hash table entries: 16384 (order: 4, 65536 bytes) [ 0.185821] TCP: Hash tables configured (established 16384 bind 16384) [ 0.185821] TCP reno registered [ 0.185852] UDP hash table entries: 256 (order: 0, 4096 bytes) [ 0.185882] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes) [ 0.186126] NET: Registered protocol family 1 [ 0.186462] RPC: Registered named UNIX socket transport module. [ 0.186462] RPC: Registered udp transport module. [ 0.186492] RPC: Registered tcp transport module. [ 0.186492] RPC: Registered tcp NFSv4.1 backchannel transport module. [ 0.186798] NetWinder Floating Point Emulator V0.97 (double precision) [ 0.341857] ashmem: initialized [ 0.342193] VFS: Disk quotas dquot_6.5.2 [ 0.342254] Dquot-cache hash table entries: 1024 (order 0, 4096 bytes) [ 0.343292] fuse init (API version 7.17) [ 0.343566] msgmni has been set to 995 [ 0.344879] io scheduler noop registered [ 0.344909] io scheduler deadline registered [ 0.345001] io scheduler cfq registered (default) [ 0.345642] Could not set LED4 to fully on [ 0.347015] omap_uart.0: ttyO0 at MMIO 0x44e09000 (irq = 72) is a OMAP UART0 [ 0.967834] console [ttyO0] enabled [ 0.971984] omap_uart.1: ttyO1 at MMIO 0x48022000 (irq = 73) is a OMAP UART1 [ 0.979736] omap_uart.2: ttyO2 at MMIO 0x48024000 (irq = 74) is a OMAP UART2 [ 0.987457] omap_uart.3: ttyO3 at MMIO 0x481a6000 (irq = 44) is a OMAP UART3 [ 0.995208] omap_uart.4: ttyO4 at MMIO 0x481a8000 (irq = 45) is a OMAP UART4 [ 1.002929] omap_uart.5: ttyO5 at MMIO 0x481aa000 (irq = 46) is a OMAP UART5 [ 1.010833] [drm] Initialized drm 1.1.0 20060810 [ 1.023223] brd: module loaded [ 1.030578] loop: module loaded [ 1.034057] i2c-core: driver [tsl2550] using legacy suspend method [ 1.040557] i2c-core: driver [tsl2550] using legacy resume method [ 1.046997] at24 1-0051: 32768 byte 24c256 EEPROM, writable, 64 bytes/write [ 1.108428] No daughter card found on AM335x EVM [ 1.113311] at24 1-0050: 32768 byte 24c256 EEPROM, writable, 64 bytes/write [ 1.128540] Board name: A335BNLT [ 1.131927] Board version: 0A5A [ 1.135253] The board is a AM335x Beaglebone Black. [ 1.142242] tps65217 1-0024: TPS65217 ID 0xe version 1.2 [ 1.149688] print_constraints: DCDC1: 900 <--> 1800 mV at 1500 mV [ 1.158081] print_constraints: DCDC2: 900 <--> 3300 mV at 1100 mV [ 1.166473] print_constraints: DCDC3: 900 <--> 1500 mV at 1100 mV [ 1.174865] print_constraints: LDO1: 1000 <--> 3300 mV at 1800 mV [ 1.183258] print_constraints: LDO2: 900 <--> 3300 mV at 3300 mV [ 1.191528] print_constraints: LDO3: 1800 <--> 3300 mV at 1800 mV [ 1.199920] print_constraints: LDO4: 1800 <--> 3300 mV at 3300 mV [ 1.209533] Maximum current provided by the USB port is 500mA which is not sufficient [ 1.209533] when operating @OPP120, OPPTURBO and OPPNITRO. The current requirement for some [ 1.209564] use-cases using OPP100 might also exceed the maximum current that the [ 1.209564] USB port can provide. Unless you are fully confident that the current [ 1.209594] requirements for OPP100 use-case don't exceed the USB limits, switching [ 1.209594] to AC power is recommended. [ 1.254730] omap_hsmmc.0: alias fck already exists [ 1.260070] omap_hsmmc.1: alias fck already exists [ 1.265411] omap_i2c.3: alias fck already exists [ 1.270629] omap_i2c omap_i2c.3: bus 3 rev2.4.0 at 100 kHz [ 1.277252] davinci-mcasp.0: alias fck already exists [ 1.284271] at24 3-0054: 32768 byte 24c256 EEPROM, writable, 64 bytes/write [ 1.291564] IN : bone_setup_display_daughter_board [ 1.348449] No display cape found on BeagleBone [ 1.353790] da8xx_lcdc.0: alias fck already exists [ 1.359161] da8xx_lcdc da8xx_lcdc.0: GLCD: Found nxp-1280x720@60 panel [ 1.511108] tda998x 1-0070: found TDA19988 [ 3.548522] tda998x 1-0070: failed to read EDID [ 3.559143] Setup HDMI display complete [ 3.563201] at24 3-0055: 32768 byte 24c256 EEPROM, writable, 64 bytes/write [ 3.570526] IN : bone_setup_daughter_board [ 3.628570] at24 3-0056: 32768 byte 24c256 EEPROM, writable, 64 bytes/write [ 3.635864] IN : bone_setup_daughter_board [ 3.698547] at24 3-0057: 32768 byte 24c256 EEPROM, writable, 64 bytes/write [ 3.705841] IN : bone_setup_daughter_board [ 3.768737] (hci_tty): inside hci_tty_init [ 3.773223] (hci_tty): allocated 251, 0 [ 3.777404] NFC Driver for TI WiLink [ 3.782043] mtdoops: mtd device (mtddev=name/number) must be supplied [ 3.789184] omap2-nand driver initializing [ 3.793548] OneNAND driver initializing [ 3.798187] CAN device driver interface [ 3.802215] CAN bus driver for Bosch D_CAN controller 1.0 [ 3.858520] davinci_mdio davinci_mdio.0: davinci mdio revision 1.6 [ 3.864990] davinci_mdio davinci_mdio.0: detected phy mask fffffffe [ 3.872497] davinci_mdio.0: probed [ 3.876098] davinci_mdio davinci_mdio.0: phy[0]: device 0:00, driver SMSC LAN8710/LAN8720 [ 3.884735] PPP generic driver version 2.4.2 [ 3.889465] PPP BSD Compression module registered [ 3.894378] PPP Deflate Compression module registered [ 3.899810] usbcore: registered new interface driver cdc_ether [ 3.906005] usbcore: registered new interface driver cdc_eem [ 3.912017] usbcore: registered new interface driver dm9601 [ 3.917907] usbcore: registered new interface driver cdc_subset [ 3.924163] cdc_ncm: 04-Aug-2011 [ 3.927612] usbcore: registered new interface driver cdc_ncm [ 3.933654] usbcore: registered new interface driver cdc_acm [ 3.939605] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters [ 3.947998] Initializing USB Mass Storage driver... [ 3.953277] usbcore: registered new interface driver usb-storage [ 3.959594] USB Mass Storage support registered. [ 3.964630] usbcore: registered new interface driver usbserial [ 3.970825] USB Serial support registered for generic [ 3.976196] usbcore: registered new interface driver usbserial_generic [ 3.983032] usbserial: USB Serial Driver core [ 3.987640] USB Serial support registered for GSM modem (1-port) [ 3.994110] usbcore: registered new interface driver option [ 3.999969] option: v0.7.2:USB Driver for GSM modems [ 4.007202] gadget: Mass Storage Function, version: 2009/09/11 [ 4.013458] gadget: Number of LUNs=1 [ 4.017303] lun0: LUN: removable file: (no medium) [ 4.022705] gadget: android_usb ready [ 4.026641] musb-hdrc musb-hdrc.0: MUSB HDRC host driver [ 4.032287] musb-hdrc musb-hdrc.0: new USB bus registered, assigned bus number 2 [ 4.040191] usb usb2: New USB device found, idVendor=1d6b, idProduct=0002 [ 4.047302] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1 [ 4.054870] usb usb2: Product: MUSB HDRC host driver [ 4.060089] usb usb2: Manufacturer: Linux 3.2.0-00245-g03f2a1e musb-hcd [ 4.066986] usb usb2: SerialNumber: musb-hdrc.0 [ 4.072357] hub 2-0:1.0: USB hub found [ 4.076324] hub 2-0:1.0: 1 port detected [ 4.081268] mousedev: PS/2 mouse device common for all mice [ 4.088531] using rtc device, am33xx-rtc, for alarms [ 4.093597] omap_rtc am33xx-rtc: rtc core: registered am33xx-rtc as rtc0 [ 4.100952] i2c /dev entries driver [ 4.105010] Linux video capture interface: v2.00 [ 4.110260] usbcore: registered new interface driver uvcvideo [ 4.116271] USB Video Class driver (1.1.1) [ 4.123718] OMAP Watchdog Timer Rev 0x01: initial timeout 60 sec [ 4.130340] device-mapper: uevent: version 1.0.3 [ 4.135406] device-mapper: ioctl: 4.22.0-ioctl (2011-10-19) initialised: dm-devel@redhat.com [ 4.144256] Bluetooth: HCI UART driver ver 2.2 [ 4.148925] Bluetooth: HCI H4 protocol initialized [ 4.153930] Bluetooth: HCILL protocol initialized [ 4.158874] Bluetooth: Bluetooth Driver for TI WiLink - Version 1.0 [ 4.241729] cpuidle: using governor ladder [ 4.246429] cpuidle: using governor menu [ 4.255798] usbcore: registered new interface driver usbhid [ 4.261810] usbhid: USB HID core driver [ 4.266754] logger: created 256K log 'log_main' [ 4.271820] logger: created 256K log 'log_events' [ 4.277038] logger: created 256K log 'log_radio' [ 4.282165] logger: created 256K log 'log_system' [ 4.288208] usbcore: registered new interface driver snd-usb-audio [ 4.298919] asoc: am335x-hdmi-hifi <-> davinci-mcasp.0 mapping ok [ 4.306793] ALSA device list: [ 4.309997] #0: AM335X BONE [ 4.313140] oprofile: hardware counters not available [ 4.318542] oprofile: using timer interrupt. [ 4.323303] Netfilter messages via NETLINK v0.30. [ 4.328491] nf_conntrack version 0.5.0 (7966 buckets, 31864 max) [ 4.335601] ctnetlink v0.93: registering with nfnetlink. [ 4.341369] NF_TPROXY: Transparent proxy support initialized, version 4.1.0 [ 4.348785] NF_TPROXY: Copyright (c) 2006-2007 BalaBit IT Ltd. [ 4.355529] xt_time: kernel timezone is -0000 [ 4.360656] ip_tables: (C) 2000-2006 Netfilter Core Team [ 4.366699] arp_tables: (C) 2002 David S. Miller [ 4.371765] TCP cubic registered [ 4.375518] NET: Registered protocol family 10 [ 4.381774] Mobile IPv6 [ 4.384460] ip6_tables: (C) 2000-2006 Netfilter Core Team [ 4.390625] IPv6 over IPv4 tunneling driver [ 4.396270] NET: Registered protocol family 17 [ 4.401092] NET: Registered protocol family 15 [ 4.405792] can: controller area network core (rev 20090105 abi 8) [ 4.412597] NET: Registered protocol family 29 [ 4.417297] can: raw protocol (rev 20090105) [ 4.421875] can: broadcast manager protocol (rev 20090105 t) [ 4.428192] Bluetooth: RFCOMM TTY layer initialized [ 4.433502] Bluetooth: RFCOMM socket layer initialized [ 4.438964] Bluetooth: RFCOMM ver 1.11 [ 4.442932] Bluetooth: BNEP (Ethernet Emulation) ver 1.3 [ 4.448608] Bluetooth: BNEP filters: protocol multicast [ 4.454132] Bluetooth: HIDP (Human Interface Emulation) ver 1.2 [ 4.460723] Registering the dns_resolver key type [ 4.465820] VFP support v0.3: implementor 41 architecture 3 part 30 variant c rev 3 [ 4.473999] ThumbEE CPU extension supported. [ 4.478607] mux: Failed to setup hwmod io irq -22 [ 4.484924] Power Management for AM33XX family [ 4.489990] Trying to load am335x-pm-firmware.bin (60 secs timeout) [ 4.496734] Copied the M3 firmware to UMEM [ 4.501220] Cortex M3 Firmware Version = 0x181 [ 4.512847] clock: disabling unused clocks to save power [ 4.521179] Detected MACID=c8:a0:30:c5:9:31 [ 4.527862] omap_rtc am33xx-rtc: setting system clock to 2000-01-01 00:00:01 UTC (946684801) [ 4.537872] Waiting for root device /dev/mmcblk0p2... [ 4.579559] mmc0: host does not support reading read-only switch. assuming write-enable. [ 4.590148] mmc0: new high speed SDHC card at address b368 [ 4.596893] mmcblk0: mmc0:b368 USD 7.46 GiB [ 4.604034] mmcblk0: p1 p2 p3 p4 [ 4.669952] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null) [ 4.678710] VFS: Mounted root (ext4 filesystem) on device 179:2. [ 4.686157] Freeing init memory: 344K [ 4.710418] mmc1: new high speed MMC card at address 0001 [ 4.717895] mmcblk1: mmc1:0001 MMC02G 1.78 GiB [ 4.723937] mmcblk1boot0: mmc1:0001 MMC02G partition 1 1.00 MiB [ 4.731719] mmcblk1boot1: mmc1:0001 MMC02G partition 2 1.00 MiB [ 4.743499] mmcblk1: p1 p2 [ 4.753356] mmcblk1boot1: unknown partition table [ 4.759307] init (1): /proc/1/oom_adj is deprecated, please use /proc/1/oom_score_adj instead. [ 4.771759] mmcblk1boot0: unknown partition table [ 4.945861] init: cannot open '/initlogo.rle' [ 5.057067] EXT4-fs (mmcblk0p3): mounted filesystem with ordered data mode. Opts: nomblk_io_submit,errors=panic [ 5.109771] init: cannot find '/system/etc/install-recovery.sh', disabling 'flash_recovery' [ 5.179168] android_usb: already disabled [ 5.191558] android_usb: already disabled [ 5.197265] android_usb: already disabled [ 5.203063] adb_bind_config [ 5.208496] adb_bind_config [ 5.257568] adb_open [ 5.430084] android_work: sent uevent USB_STATE=CONNECTED root@android:/ #
Nas próximas inicializações (talvez) não seja necessário apertar novamente o botão USER/BOOT. Caso não funcione, pressione novamente o botão para iniciar a placa.
Abaixo uma imagem na TV do Android rodando pela Beaglebone Black.
Conclusão
Este artigo procura ilustrar de forma simplificada como construir uma imagem Android para uma BeagleBone Black. Espero que possa ajudar aos aventureiros em suas primeiras viagens em um nível mais baixo neste badalado sistema operacional embarcado.
Uma vez com uma imagem Android presente em sua Beaglebone Black, você poder começar a desenvolver software utilizando os conceitos apresentados pelo artigo do André Prado.







Por que é mandatário que o SO e o Java sejam 64bits?
Saudações Flavio. Você poderia informar como proceder para compilar o Android em uma placa que não seja o Beagle Bone Black? Possuo uma placa chinesa chamada FriendlyArm Mini210S e gostaria de instalar o Android 5.1. Infelizmente, apenas recebi a imagem para o Android 2.3 e 4.0. Tenho o toolchain dessa placa e o código fonte do Android 2.3 e 4.0 dessa placa. É possível proceder para a compilação de uma nova versão? Muito obrigado.
Cara. Eu estava acompanhando o passo-a-passo de toda a linha de comando…
Na parte de baixar fonte do Android: “../bin/repo init -u git://gitorious.org/rowboat/manifest.git -m rowboat-jb-am335x.xml”
Tenho os eguinte erro: “Permission Denied”.
Sabe me dizer o porque?!
Olá Victor, tudo bem?
Não é problema de permissão de escrita no diretório onde será baixado o Android não?
No tutorial, preve-se que o Android será compilado no diretório home do usuário da estação de trabalho. Caso você tenha usado qualquer outro diretório, problemas com permissão de arquivo podem ocorrer.
Espero ter ajudado.
Abraço,
Flavio
Flavio parabéns pelo artigo, excelente iniciativa. Tive alguns problemas realizando do zero e vou postar aqui como resolvi caso acontecer com mais alguém: Primeiro meu host é um Intel Core i5 com Linux Mint 13 Maya 64bits com kernel 3.8. 1) Em adquirir o Java SE JDK por ser um versão old tive que fazer login para baixar o .bin mas é bom ter este cadastro em mãos. 2) Quando execute o o .bin ele não instalou em /opt, então eu movi para /opt e criei um .sh com echo -e ‘nexport PATH=”/opt/jdk1.6.0_45/bin:$PATH” 3) Iniciei o make, ae notei varias… Leia mais »
Parabéns pelo artigo, Flávio. Muito bom!
Obrigado por compartilhar sua experiência. Vou encaminhar a um amigo.
Irado o tutorial! =)
Show de bola! Gostei muito desse artigo!
Não consegui executar o repo:
../bin/repo init -u git://gitorious.org/rowboat/manifest.git -m rowboat-jb-am335x.xml
Get https://gerrit.googlesource.com/git-repo/clone.bundle
Get https://gerrit.googlesource.com/git-repo
Get git://gitorious.org/rowboat/manifest.git
fatal: unable to connect to gitorious.org:
gitorious.org[0: 64.13.172.37]: errno=Conexão recusada
fatal: unable to connect to gitorious.org:
gitorious.org[0: 64.13.172.37]: errno=Conexão recusada