julho 21, 2013

Introdução ao funcionamento interno do Android

Android está na moda. E não esta­mos falando de nen­hum novo roboz­inho da Sony ou da Honda. Esta­mos falando do sis­tema opera­cional do Google (ou da Google, como preferirem), desen­volvido espe­cial­mente para dis­pos­i­tivos móveis.
Como é um sis­tema aberto (ape­sar de não ter nec­es­sari­a­mente todo código-fonte disponível), todos querem embar­car o Android em seus dis­pos­i­tivos e se aproveitar de toda a infraestru­tura de apli­cações e serviços disponíveis no mercado.
Uma car­ac­terís­tica que ajuda na escolha deste sis­tema opera­cional é que ele usa o ker­nel do Linux. Mas o que isso sig­nifica? O Android é uma dis­tribuição Linux? Como ele fun­ciona inter­na­mente? É isso que ver­e­mos nesta série de arti­gos sobre a arquite­tura interna do Android.
HISTÓRICO
Em 2005, uma empresa chamada Android Inc., que desen­volvia um sis­tema opera­cional móvel de mesmo nome, foi com­prada pelo Google. Com a pop­u­lar­iza­ção do uso de smart­phones trazida pelo iPhone da Apple, o Google sen­tiu que pode­ria expandir seu negó­cio de venda de anún­cios tam­bém em dis­pos­i­tivos móveis.
Em 2007, para cuidar do pro­jeto Android, o Google criou a Open Hand­set Alliance, um con­sór­cio de empre­sas de tec­nolo­gia envolvi­das no mer­cado de dis­pos­i­tivos móveis (HTC, Sony, Intel, Motorola, San­sumg, etc). No fim deste mesmo ano, é lib­er­ada a primeira ver­são do Android, jun­ta­mente com o SDK para o desen­volvi­mento de apli­cações.
ARQUITETURA BÁSICA
O Android é um sis­tema opera­cional baseado no ker­nel do Linux. Ape­sar de ter sido desen­volvido ini­cial­mente para smart­phones, hoje é usado em diver­sas out­ras apli­cações como tablets e até reló­gios
Ape­sar de ser baseado no ker­nel do Linux, existe pouca coisa em comum com dis­tribuições Linux con­ven­cionais (embar­cadas ou não). À grosso modo, o Android é uma máquina vir­tual Java rodando sobre o ker­nel do Linux, dando suporte para o desen­volvi­mento de apli­cações Java através de um con­junto de bib­liote­cas e serviços. Sua arquite­tura tem basi­ca­mente 4 camadas:
system architecture Introdução ao funcionamento interno do Android
Linux ker­nel: o Android usa o ker­nel do Linux com alguns patchs, que adi­cionam algu­mas fun­cional­i­dades através de módu­los do ker­nel. Ver­e­mos mais adi­ante quais são estas fun­cional­i­dades.
Bib­liote­cas e serviços: aqui estão as bib­liote­cas bási­cas do sis­tema como a Bionic, aOpenGL/ES para tra­bal­har com grá­fi­cos, e a SQLite para tra­bal­har com banco de dados. Aqui tam­bém estão os serviços provi­dos para as camadas supe­ri­ores, incluindo a máquina vir­tual Java (Dalvik). A maior parte destas bib­liote­cas e serviços estão desen­volvi­dos em C e C++.
Frame­work: esta camada é desen­volvida quase toda em Java, e faz a inter­face com as apli­cações Android. Ela provê um con­junto de bib­liote­cas para aces­sar os diver­sos recur­sos do dis­pos­i­tivo como inter­face grá­fica, tele­fo­nia, local­izador (GPS), banco de dados per­sis­tente, armazena­mento no cartão SD, etc.
Apli­cações: é aqui que ficam as apli­cações (desen­volvi­das em Java) para o Android. E é um dos grandes seg­re­dos do sucesso da plataforma, já que pos­sui mais de 250.000 apli­cações no Android Mar­ket, e con­tinua crescendo cada dia que passa.
Para uma descrição mais com­pleta da arquite­tura do Android, dê uma olhada no guia de desen­volvi­mento Android disponi­bi­lizado pelo Google.
Parece sim­ples, não? Nem tanto assim. Se olhar­mos para a arquite­tura interna do Android, ver­e­mos o nível de com­plex­i­dade deste sis­tema opera­cional:
Android internals 1024 Introdução ao funcionamento interno do Android
Real­mente muita coisa acon­tece quando rodamos uma sim­ples apli­cação. Vamos então ten­tar enten­der mel­hor tudo isso?
KERNEL
Vimos que o Android usa uma ver­são mod­i­fi­cada do ker­nel do Linux. Den­tre as prin­ci­pais mod­i­fi­cações, temos:
binder: sabemos que em todo sis­tema opera­cional com suporte à memória vir­tual, os proces­sos rodam em difer­entes regiões de memória. Isso sig­nifica que nen­hum processo tem acesso à região de memória de outro processo. E por isso pre­cisamos de um mecan­ismo de comu­ni­cação entre proces­sos. Mas quem esta acos­tu­mado com o padrão Sys­tem V IPCusado em sis­temas Linux tradi­cionais para comu­ni­cação entre proces­sos (mes­sage queues, semá­foros e shared mem­ory) vai pre­cisar “voltar à escola”. O Android usa o Binder para a comu­ni­cação entre proces­sos. Ele imple­menta um mod­ulo no ker­nel em “drivers/misc/binder.c” para esta tarefa. Toda comu­ni­cação entre proces­sos no Android passa pelo binder. Para o desen­volve­dor de apli­cações Android, o processo é trans­par­ente, já que é abstraído pelas bib­liote­cas do sis­tema.
ashmem: um novo mecan­ismo de com­par­til­hamento de memória, onde dois proces­sos podem se comu­nicar através desta região com­par­til­hada de memória. É mais leve e sim­ples de usar, e tem mel­hor suporte a dis­pos­i­tivos com pouca memória, já que tem a capaci­dade de descar­tar regiões de memória com­par­til­hada de maneira segura em caso de pouca memória disponível. Sua imple­men­tação encontra-se em “mm/ashmem.c”.
logger: o Android pos­sui um sis­tema global de logs, imple­men­tado através de um módulo do ker­nel. Ele cria 4 arquivos de dis­pos­i­tivo em “/dev/log”, cada um rep­re­sen­tando um buffer difer­ente:
# ls -l /dev/log
crw-rw--w- root     log       10,  54 1970-01-01 00:00 system
crw-rw--w- root     log       10,  55 1970-01-01 00:00 radio
crw-rw--w- root     log       10,  56 1970-01-01 00:00 events
crw-rw--w- root     log       10,  57 1970-01-01 00:00 main
Para as apli­cações aces­sarem o sis­tema de log, basta abrir e ler ou escr­ever num destes arquivos de dis­pos­i­tivo. A imple­men­tação deste módulo no ker­nel encontra-se em “drivers/misc/logger.c”.
wakelocks: se um dis­pos­i­tivo Android ficar um tempo sem ser usado, entrará em modo de baixo con­sumo para garan­tir econo­mia de bate­ria. O módulo de wake­lock per­mite que as apli­cações desabilitem o mecan­ismo de baixo con­sumo. Por exem­plo, se você pre­cisar exe­cu­tar um processo em back­ground que não pode ser inter­rompido para entrar em modo de baixo con­sumo, este módulo pos­si­bilita a desati­vação tem­porária deste recurso até que seu processo final­ize a exe­cução. Sua imple­men­tação encontra-se em “kernel/power/wakelock.c”.
oom han­dling: imple­men­tado em “drivers/misc/lowmemorykiller.c”, con­trola o uso de memória do sis­tema e mata proces­sos se ver­i­ficar que a memória disponível esta abaixo de um valor mín­imo aceitável.
timed GPIO: possibilita acionar saí­das de I/O de forma tem­po­rizada. Está imple­men­tado em “drives/misc/timed_gpio.c”.
SISTEMA DE ARQUIVOS
Esta é a árvore de diretórios de um sis­tema de arquivos para o Android:
$ sudo tree -d -L 2 .
.
|-- acct
|   `-- uid
|-- cache
|   `-- lost+found
|-- config
|-- d -> /sys/kernel/debug
|-- data
|   |-- anr
|   |-- app
|   |-- app-private
|   |-- backup
|   |-- bootchart
|   |-- dalvik-cache
|   |-- data
|   |-- dontpanic
|   |-- local
|   |-- lost+found
|   |-- misc
|   |-- property
|   |-- secure
|   |-- system
|   `-- tombstones
|-- dev
|-- mnt
|   |-- asec
|   |-- sdcard
|   `-- secure
|-- part-3
|-- proc
|-- sbin
|-- sys
`-- system
    |-- app
    |-- bin
    |-- etc
    |-- fonts
    |-- framework
    |-- lib
    |-- media
    |-- ti-dsp
    |-- usr
    `-- xbin
Bem difer­ente de um sis­tema Linux con­ven­cional, não é ver­dade? Os dois prin­ci­pais diretórios são o “data”, que armazena os dados das apli­cações, e o “sys­tem”, com as bib­liote­cas (system/lib), serviços (system/bin e system/xbin) e apli­cações Java (system/app).
E por falar em bib­liote­cas do sis­tema, nada de glibc ou uClibc. O Android imple­men­tou uma bib­lioteca chamada Bionic para usar como bib­lioteca do sis­tema. Porque? Me parece que o Google tem algum prob­lema com licenças GPL, e eles tiraram do user space todo e qual­quer soft­ware com licença GPL. A Bionic usa a licensa BSD, e suporta as arquite­turas x86 e ARM.
Agora, se alguém do Google esta lendo este artigo, por favor me respon­dam, porque vocês não usaram o Busy­box??? Bom, tenho quase certeza de que tam­bém tem a ver com a licensaGPL do Busy­box. De qual­quer forma, o Android usa o Tool­box, uma imple­men­tação no mesmo esquema do Busy­box, que tam­bém traz um con­junto (mais lim­i­tado) de coman­dos e fer­ra­men­tas úteis para geren­ciar um sis­tema Android. Repare nos exe­cutáveis que fazem um link para o tool­box na listagem abaixo:
$ ls -l /system/bin
lrwxrwxrwx system   system            2011-08-13 04:24 reboot -> toolbox
-rwxr-xr-x system   system       9648 2011-08-13 04:24 audioloop
-rwxr-xr-x system   system     100916 2011-08-13 04:24 iptables
-rwxr-xr-x system   system       9748 2011-08-13 04:24 sdcard
lrwxrwxrwx system   system            2011-08-13 04:24 ps -> toolbox
lrwxrwxrwx system   system            2011-08-13 04:24 top -> toolbox
-rw-r--r-- system   system       5372 2011-08-13 04:24 testwrap
lrwxrwxrwx system   system            2011-08-13 04:24 mount -> toolbox
-rwxr-xr-x system   system       5548 2011-08-13 04:24 dvz
-rwxr-xr-x system   system      18112 2011-08-13 04:24 debuggerd
lrwxrwxrwx system   system            2011-08-13 04:24 ln -> toolbox
lrwxrwxrwx system   system            2011-08-13 04:24 ifconfig -> toolbox
lrwxrwxrwx system   system            2011-08-13 04:24 renice -> toolbox
-rwxr-xr-x system   system      10792 2011-08-13 04:24 showlease
drwxr-xr-x system   system            2011-08-13 04:24 sgx
lrwxrwxrwx system   system            2011-08-13 04:24 start -> toolbox
...
O Android ainda usa por padrão o SQLite como geren­ci­ador de banco de dados para as apli­cações e o OpenGl/ES como bib­lioteca grá­fica, den­tre out­ras bib­liote­cas disponíveis.
OS SERVIÇOS BÁSICOS
Se lis­tar­mos os proces­sos rodando em um dis­pos­i­tivo com Android, a saída será mais ou menos essa:
# ps
USER     PID   PPID  VSIZE  RSS     WCHAN    PC         NAME
root      1     0     504    416   c00c1b9c 0000877c S /init
root      2     0     0      0     c0072c34 00000000 S kthreadd
root      3     2     0      0     c00656f0 00000000 S ksoftirqd/0
root      4     2     0      0     c008a23c 00000000 S watchdog/0
root      5     2     0      0     c006fc14 00000000 S events/0
root      6     2     0      0     c006fc14 00000000 S khelper
root      10    2     0      0     c0078bc8 00000000 S async/mgr
root      13    2     0      0     c006fc14 00000000 S suspend
root      229   2     0      0     c009ef8c 00000000 S sync_supers
root      231   2     0      0     c009f7bc 00000000 S bdi-default
root      233   2     0      0     c006fc14 00000000 S kblockd/0
root      246   2     0      0     c006fc14 00000000 S ksuspend_usbd
root      250   2     0      0     c0240bc4 00000000 S khubd
root      253   2     0      0     c0269074 00000000 S kseriod
root      261   2     0      0     c006fc14 00000000 S twl4030-irqchip
root      262   2     0      0     c0207a40 00000000 S twl4030-irq
root      292   2     0      0     c006fc14 00000000 S kmmcd
root      308   2     0      0     c006fc14 00000000 S musb_hdrc
root      310   2     0      0     c006fc14 00000000 S rpciod/0
root      319   2     0      0     c008a434 00000000 S khungtaskd
root      320   2     0      0     c009a628 00000000 S kswapd0
root      322   2     0      0     c006fc14 00000000 S aio/0
root      323   2     0      0     c006fc14 00000000 S nfsiod
root      324   2     0      0     c006fc14 00000000 S crypto/0
root      474   2     0      0     c021a7f0 00000000 S mtdblockd
root      546   2     0      0     c006fc14 00000000 S kondemand/0
root      547   2     0      0     c006fc14 00000000 S kconservative/0
root      553   2     0      0     c006fc14 00000000 S usbhid_resumer
root      557   2     0      0     c02e760c 00000000 S binder_deferred
root      589   2     0      0     c02d7f9c 00000000 S mmcqd
root      609   1     488    172   c00c1b9c 0000877c S /sbin/ueventd
root      887   1     736    332   c00633f0 afd0c63c S /system/bin/sh
system    889   1     808    248   c02e69e8 afd0b81c S /system/bin/servicemanager
root      890   1     3864   584   ffffffff afd0becc S /system/bin/vold
root      891   1     3836   556   ffffffff afd0becc S /system/bin/netd
root      892   1     668    256   c031bfb8 afd0c1ec S /system/bin/debuggerd
root      893   1     1272   540   c0076e64 afd0becc S /system/bin/rild
root      894   1     61364  26520 c00c1b9c afd0b964 S zygote
media     895   1     26872  5132  ffffffff afd0b81c S /system/bin/mediaserver
bluetooth 896   1     1256   564   c00c1b9c afd0c82c S /system/bin/dbus-daemon
root      897   1     816    308   c0373d78 afd0b57c S /system/bin/installd
keystore  898   1     1744   424   c031bfb8 afd0c1ec S /system/bin/keystore
system    899   1     736    328   c00633f0 afd0c63c S /system/bin/sh
root      901   1     3352   156   ffffffff 00008294 S /sbin/adbd
root      948   2     0      0     c006fc14 00000000 S pvr_timer/0
root      962   2     0      0     c006fc14 00000000 S pvr_workqueue
system    978   894   166280 70284 ffffffff afd0b81c S system_server
root      988   2     0      0     c006fc14 00000000 S omaplfb
app_21    1057  894   78324  23540 ffffffff afd0c7ac S com.android.inputmethod.latin
radio     1066  894   85216  23928 ffffffff afd0c7ac S com.android.phone
system    1067  894   76424  27816 ffffffff afd0c7ac S com.android.systemuiueventd
app_14    1068  894   83528  33064 ffffffff afd0c7ac S com.android.launcher
app_3     1120  894   76456  23620 ffffffff afd0c7ac S android.process.acore
app_1     1180  894   73848  22596 ffffffff afd0c7ac S com.android.email
app_4     1192  894   73320  22316 ffffffff afd0c7ac S android.process.media
app_2     1215  894   71424  21416 ffffffff afd0c7ac S com.android.bluetooth
app_10    1243  894   72164  21456 ffffffff afd0c7ac S com.android.deskclock
app_25    1263  894   81444  21620 ffffffff afd0c7ac S com.android.mms
app_26    1290  894   72016  21800 ffffffff afd0c7ac S com.android.providers.calendar
app_16    1309  894   71832  21144 ffffffff afd0c7ac S com.android.quicksearchbox
app_17    1323  894   71388  20588 ffffffff afd0c7ac S com.android.music
app_27    1336  894   70796  20068 ffffffff afd0c7ac S com.android.protips
app_13    1352  894   72452  21376 ffffffff afd0c7ac S com.cooliris.media
root      5267  2     0      0     c00ced38 00000000 S flush-0:12
system    5336  899   884    272   c0076e64 afd0becc S sleep
root      5348  887   896    312   00000000 afd0b57c R ps
root      5349  1     740    332   c00633f0 afd0c63c S /system/bin/sh
Três pon­tos inter­es­santes aqui:
1. O processo “init” é o pai de todos os proces­sos que rodam em user space, como o “/sbin/ueventd” e o “/system/bin/mediaserver”.
2. O processo “kthreadd” é o pai de todas as threads do ker­nel como o “ksoftirqd” e o “khelper”.
3. O processo “zygote” é o pai de todas as apli­cações rodando no Android, como o “android.process.media” e o “com.android.email”. Tudo que roda em cima de uma máquina vir­tual, tem como ante­ces­sor comum o processo “zygote”.
MÁQUINA VIRTUAL DALVIK
E por falar em máquina vir­tual, o Android usa uma imple­men­tação da JVM chamada Dalvik. A Dalvik não con­some byte­code Java, mas sim dex­code. Para isso, o Google desen­volveu uma fer­ra­menta, chamada “dx”, que con­verte Java byte­codes (*.class) em dex­codes (*.dex).
Além disso, desde a ver­são 2.2 (Froyo), o Android pos­sui uma imple­men­tação de JIT (Just-in-time), que com­pila dex­codes para a arquitetura-alvo em tempo de exe­cução, tor­nando a exe­cução dos proces­sos con­sid­er­av­el­mente mais ráp­i­das, já que não pre­cisa ficar inter­pre­tando dex­codes.
Junto com a máquina vir­tual Dalvik, o Android usa o frame­work Apache Har­mony, desen­volvido pela Apache Soft­ware Fun­da­tion como bib­lioteca padrão de classes Java.
AS APLICAÇÕES
As apli­cações são escritas em Java. Exis­tem bib­liote­cas Java disponíveis para aces­sar todos os recur­sos do dis­pos­i­tivo.
Ao exe­cu­tar uma apli­cação, o processo “zygote” cria uma instân­cia da máquina vir­tual Dalvik para executá-la. E cada apli­cação roda com um UID (user ID) difer­ente. Dê uma olhada na col­una “USER” da listagem de proces­sos acima. Isso pro­tege as apli­cações umas das out­ras, e do sis­tema como um todo, lim­i­tando acesso aos arquivos do sis­tema e aos recur­sos do dis­pos­i­tivo através de per­mis­sões de usuário.

Fonte: Sergio Prado








Nenhum comentário:

Postar um comentário