Introduction
La distribution AOSP fournit une version standard d'Android pour un certain nombre de plate-formes (NEXUS, émulateur, Pandaboard, …). De même, de nombreux « forks » d'AOSP sont proposés par les fabricants de matériel afin de fournir un BSP Android adapté. Il est fréquent d'avoir à adapter ce BSP aux contraintes du produit et cette tâche peut aller de la simple « customisation » (modification de l'image de fond d'écran au démarrage ou de l'animation de chargement) à l'ajout de pilotes noyau ou d'applications dédiées. Les même techniques peuvent bien entendu être utilisées pour ajouter à AOSP une nouvelle cible dérivée d'une cible existante, comme lors du développement d'une carte spéciale en partant d'une carte d'évaluation.
Dans cet article nous allons décrire brièvement les techniques de customisation d'AOSP en utilisant l'exemple de diverses plate-formes comme la Beaglebone Black (BB Black), la Pandaboard, la Wandboard (i.MX6) ou bien l'émulateur Android goldfish.
Les différents fichiers de configuration
Comme nous l'avons vu dans les premiers articles, AOSP utilise un principe de configuration assez simple basé sur des fichiers Makefile (syntaxe GNU-Make) et des scripts shell. Le répertoire device des sources AOSP contient la majorité des configurations des différentes plate-formes supportées. Pour un constructeur donné, les fichiers de configuration sont localisés dans device/<constructeur>, soit par exemple device/ti. Nous présentons ci-dessous un extrait du BSP Android (rowboat) pour les cartes Beaglebone à base de processeurs TI (Sitara).
$ ls -l device/ti total 16 drwxrwxr-x 8 pierre pierre 4096 Dec 3 18:10 am335xevm drwxrwxr-x 8 pierre pierre 4096 Dec 3 18:10 am335xevm_sk drwxrwxr-x 6 pierre pierre 4096 Dec 3 18:10 beaglebone drwxrwxr-x 5 pierre pierre 4096 Mar 10 14:18 beagleboneblack
Nous pouvons explorer le contenu du répertoire correspondant à la BB Black. Nous avons placé en gras les fichiers les plus importants.
$ cd device/ti/beagleboneblack/ $ ls Android.mk egl.cfg media_profiles.xml AndroidProducts.mk fstab.am335xevm mixer_paths.xml BoardConfig.mk gpio-keys.kl overlay CleanSpec.mk init.am335xevm.rc ti-tsc.idc audio_policy.conf init.am335xevm.usb.rc ueventd.am335xevm.rc beagleboneblack.mk liblights vold.fstab device.mk media_codecs.xml
Le fichier AndroidProducts.mk définit la liste des cibles concernées, soit uniquement la BB Black dans notre cas ce qui nous ramène au fichier beagleboneblack.mk .
$ cat AndroidProducts.mk ... PRODUCT_MAKEFILES := $(LOCAL_DIR)/beagleboneblack.mk
Dans le cas de la BB Black, ce fichier est relativement bref ce qui nous permet de le présenter entièrement. Une première partie concerne la modification de variables d'environnement (en gras) ce qui permet d'ajouter des paquets à l'image ou bien modifier certaines propriétés Android. Lors de la compilation d'AOSP, les propriétés seront ajoutées au fichier system/build.prop.
# Live Wallpapers PRODUCT_PACKAGES += \ LiveWallpapers \ LiveWallpapersPicker \ MagicSmokeWallpapers \ VisualizationWallpapers \ librs_jni PRODUCT_PROPERTY_OVERRIDES := \ net.dns1=8.8.8.8 \ net.dns2=8.8.4.4
Une deuxième partie décrit l'héritage de configuration à partir d'autres fichiers. En particulier, le fichier build/target/product/full_base.mk définit la configuration pour la construction d'une image AOSP générique contenant les composants open source. Le fichier device.mk contient d'autres définitions qui pourraient être partagées avec une autre cible si le fichier AndroidProducts.mk en contenait plusieurs.
# Inherit from those products. Most specific first. $(call inherit-product, $(SRC_TARGET_DIR)/product/full_base.mk) $(call inherit-product, device/ti/beagleboneblack/device.mk)
Les dernières lignes renseignent les variables d'identification de la cible (nom du produit, modèle, nom du fabricant, etc.). Le détail est disponible à l'adresse http://www.kandroid.org/online-pdk/guide/build_new_device.html ou bien au chapitre 4 de l'ouvrage Embedded Android cité en bibliographie.
PRODUCT_NAME := beagleboneblack PRODUCT_DEVICE := beagleboneblack PRODUCT_BRAND := Android PRODUCT_MODEL := BEAGLEBONEBLACK PRODUCT_MANUFACTURER := Texas_Instruments_Inc
Le fichier device.mk permet de décrire d'autres fonctionnalités comme la copie de fichier ou l'overlay. La copie utilise la variable PRODUCT_COPY_FILES. La syntaxe est très simple, la source étant séparée de la destination par le caractère « deux points ». Dans l'exemple suivant, le fichier device/ti/beagleboneblack/init.am335xevm.rc est copié lors de la compilation dans le répertoire root qui correspond au ramdisk initial correspondant au fichier ramdisk.img d'AOSP.
PRODUCT_COPY_FILES := \ device/ti/beagleboneblack/init.am335xevm.rc:root/init.am335xevm.rc \ ...
Dans le cas d'un overlay, l'arborescence décrite dans le répertoire overlay remplace lors de la compilation celle définie par défaut.
DEVICE_PACKAGE_OVERLAYS := \ device/ti/beagleboneblack/overlay
L'arborescence du répertoire overlay est présentée ci-après :
overlay ├── frameworks │ └── base │ ├── core │ │ └── res │ │ └── res │ │ ├── values │ │ │ └── config.xml │ │ └── xml │ │ └── storage_list.xml │ └── packages │ └── SettingsProvider │ └── res │ └── values │ └── defaults.xml └── packages └── apps └── Browser └── res └── values └── strings.xml
Le fichier BoardConfig.mk décrit la configuration matérielle de la cible. En voici un extrait :
# Use beaglebone camera cape as default BOARD_HAVE_CAMERA_CAPE := true TARGET_CPU_ABI := armeabi-v7a TARGET_CPU_ABI2 := armeabi TARGET_ARCH := arm TARGET_ARCH_VARIANT := armv7-a-neon ARCH_ARM_HAVE_TLS_REGISTER := true TARGET_NO_KERNEL := true BOARD_HAVE_BLUETOOTH := false TARGET_NO_BOOTLOADER := true TARGET_NO_RECOVERY := true BOARD_KERNEL_BASE := 0x80000000 ...
Dans certains cas ce fichier utilise une configuration conditionnelle afin – par exemple - de déterminer le pilote noyau à utiliser. Nous reproduisons ci-dessous un fichier de configuration pour un chipset i.MX6. Dans le cas d'une carte de type Wandboard, le pilote Wi-Fi à utiliser correspond à brcmfmac.ko.
ifeq ($(BOARD_WLAN_VENDOR),WANDBOARD) BOARD_WLAN_DEVICE := bcmdhd WPA_SUPPLICANT_VERSION := VER_0_8_ATHEROS WIFI_DRIVER_MODULE_PATH := "/system/bin/wifi/brcmfmac.ko" WIFI_DRIVER_MODULE_NAME := "brcmfmac" endif
Nous terminons la description par l'ajout du nom d'une nouvelle cible à AOSP. Comme nous l'avons vu dans le premier article d'introduction à AOSP, la procédure standard utilise la commande lunch. Dans le cas de la Pandaboard, le fichier vendorsetup.sh est présent dans le répertoire device/ti/panda. Ce fichier contient simplement une ligne permettant d'ajouter l'entrée à la liste affichée par lunch.
add_lunch_combo full_panda-userdebug
Ce principe n'est cependant pas systématiquement utilisé. En effet, le BSP Android de la BB Black utilise une variable TARGET_PRODUCT ajoutée à la ligne de compilation :
$ make TARGETPRODUCT=beagleboneblack
Cette variable est utilisée dans les fichiers Makefile et Android.mk de la distribution Android comme le montrent les exemples qui suivent :
ifeq ($(TARGET_PRODUCT), beagleboneblack) $(MAKE) -C kernel ARCH=arm am335x_evm_android_defconfig endif # This is for beagleboneblack camera cape ifeq ($(TARGET_PRODUCT), beagleboneblack) ifeq ($(BOARD_HAVE_CAMERA_CAPE),true) LOCAL_CFLAGS += -DCONFIG_CAMERA_CAPE endif endif
Ajout de service
Il est relativement simple d'ajouter un service lancé au démarrage d'Android. Prenons l'exemple du simple script boucle.sh effectuant toutes les secondes une trace visible par logcat.
#!/system/bin/sh echo $$ > /data/boucle.pid while [ 1 ]; do log -t MY_SERVICE boucle sleep 1 done
Après transfert du script sur la cible Android par ADB, on peut tester son fonctionnement par :
# /data/boucle.sh & # logcat
On doit alors obtenir les traces indiquant le fonctionnement de la boucle :
I/MY_SERVICE( 849): boucle I/MY_SERVICE( 850): boucle I/MY_SERVICE( 851): boucle I/MY_SERVICE( 853): boucle I/MY_SERVICE( 854): boucle I/MY_SERVICE( 855): boucle ...
Afin que boucle.sh soit lancé au démarrage du système, il suffit de modifier le script /init.rc (ou bien /init.<nom_cible>.rc) et d'y ajouter les lignes suivantes :
service my_service /data/boucle.sh class main oneshot
Ce fichier init.rc modifié peut bien entendu faire partie de la configuration spécifique de la cible dans device.
Cas particulier de l'émulateur
L'émulateur est très pratique dans le cas de premiers tests puisqu'il ne nécessite pas de matériel. La configuration est très proche de celle décrite précédemment mise à part la localisation des fichiers dans build/target/board/generic.
$ ls -l build/target/board/generic total 20 -rw-r--r-- 1 pierre pierre 29 Oct 16 10:46 AndroidBoard.mk -rw-r--r-- 1 pierre pierre 1754 Oct 16 10:46 BoardConfig.mk -rw-r--r-- 1 pierre pierre 338 Oct 16 10:46 README.txt -rw-r--r-- 1 pierre pierre 1429 Feb 13 15:57 device.mk -rw-r--r-- 1 pierre pierre 108 Oct 16 10:46 system.prop
Le fichier README.txt indique qu'il n'est pas possible de dériver la configuration de l'émulateur mais cela n'empêche pas de réaliser quelques tests !
It is not a product "base class"; no other products inherit from it or use it in any way.
Un test simple consiste à modifier le fichier device.mk afin d'ajouter une image de fond d'écran au démarrage ( initlogo.rle), une animation adaptée ( bootanimation.zip) et enfin un paquet Hello qui sera compilé avec l'image AOSP. Nous remarquons qu'il existe bien un répertoire device/generic/goldfish.
PRODUCT_COPY_FILES += \ device/generic/goldfish/bootanimation.zip:system/media/bootanimation.zip \ device/generic/goldfish/initlogo.rle:root/initlogo.rle PRODUCT_PACKAGES += \ Hello
Le répertoire Hello contenant les sources de l'application (créée avec ADT) doit être ajouté au répertoire device/generic/goldfish. Après compilation de l'image AOSP, on pourra tester la nouvelle version par la commande suivante et constater la présence de l'application dans le répertoire /data/app et bien entendu sur le bureau Android.
$ emulator -data out/target/product/generic/userdata.img &
Conclusion
Cet article nous a permis de présenter la configuration/customisation d'AOSP pour une cible matérielle. Il existe assez peu de documentation officielle sur ce sujet et il est parfois nécessaire de partir à la recherche des informations directement dans les sources du BSP Android.
Bibliographie
-
http://www.kandroid.org/online-pdk/guide/build_new_device.html
-
http://www.packtpub.com/android-systems-development-how-instant/book
-
http://rxwen.blogspot.fr/2010/01/android-property-system.html
[…] peut se référer à l’article Customisation d’AOSP, partie « Ajout de service », pour tout ce qui concerne les […]