Nachfolgend soll das Erstellen eines selbstgebauten Android-Abbildes (Custom ROM) beschrieben werden. Es werden dabei mehrere Seiten im Internet abgearbeitet.
Es wird ein DEBIAN-Linux-System vorausgesetzt, sowie eine Verbindung zum Internet, um Dateien herunterzuladen. Es kann ein Minimalinstallation als Voraussetzung genutzt werden. Nachfolgend werden alle Schritte in einer CHROOT-Umgebung durchgeführt.
Das gebaute Image wird immer für ein bestimmtes Gerät gebaut. Dafür muss das Gerät, zum Beispiel von LineageOS, unterstützt werden.
Zur Vorbereitung des Bausystems gehört das Erstellen einer geeigneten Verzeichnisstruktur, die Installation von bauabhängigen Paketen und JAVA, sowie mehreren Werkzeugen, die von anderen Quellen geholt werden.
Nachfolgend werden alle zusätzlichen Programme (zum Beispiel das SDK), die nicht als Pakete installiert werden, sowie die späteren Daten, die beim Bauen erstellt werden, in ein eigenen Unterverzeichnis gepackt. Das hat den Vorteil, dass dieses Verzeichnis bei Bedarf auch auf einen anderen Rechner kopiert und dort ebenfalls ausgeführt werdne können.
Es wird ein Verzeichnis erstellt, in dem alle Daten gespeichert werden:
~$ mkdir -p ~/AnroidCustomROM/bin
Es ist ratsam für jede Android-Version, die gebaut werden soll, ein eigenes Unterverzeichnis zu erstellen:
~$ mkdir ~/AndroidCustomROM/cm-14.1
Im zweiten Schritt müssen die Bauabhängigkeiten installiert werden:
~# apt install bc bison build-essential curl flex g++-multilib gcc-multilib git gnupg gperf imagemagick \ lib32ncurses5-dev lib32readline6-dev lib32z1-dev libesd0-dev liblz4-tool libncurses5-dev libsdl1.2-dev libwxgtk3.0-dev \ libxml2 libxml2-utils lzop pngcrush schedtool squashfs-tools xsltproc zip zlib1g-dev python
Die verschiedenen Versionen von LineageOS benötigen unterschiedliche JAVA-Versionen. Nachfolgend wird aufgrund der Vereinfachung von der Version 14.1 ausgegangen, welche OpenJDK 1.8 benötigt:
~# apt install openjdk-8-jdk
Das SDK von Google sollte auf dem System installiert werden, damit die Programme „adb
“ und „fastboot
“ in aktuellen Versionen zur Verfügung stehen. Nach dem Herunterladen des ZIP-Archives wird diese einfach im Bauverzeichnis entpackt:
~$ unzip platform-tools-latest-linux.zip -d ~/AndroidCustomROM/bin/ Archive: platform-tools-latest-linux.zip inflating: ~/AndroidCustomROM/bin/platform-tools/adb creating: ~/AndroidCustomROM/bin/platform-tools/api/ ... inflating: ~/AndroidCustomROM/bin/platform-tools/systrace/catapult/common/lab/hardware.py inflating: ~/AndroidCustomROM/bin/platform-tools/systrace/systrace.py inflating: ~/AndroidCustomROM/bin/platform-tools/systrace/NOTICE
Damit der Aufruf von „adb
“ und „fastboot
“ auch von überall aus funktioniert, ist es ratsam, das neu erstellte Verzeichnis in die Pfadumgebung mit aufzunehmen. Nachfolgend wird dies über die Datei „~/.bashrc
“ gemacht:
if [ -d "${HOME}/AndroidCustomROM/bin/platform-tools" ]; then PATH="${HOME}/AndroidCustomROM/bin/platform-tools:${PATH}"; fi;
Das Repo-Kommando dient dazu, die verschiedenen Android-GIT-Repositories zu verwalten. Es ist ein Python-Skript, welches auf GIT selbst aufbaut und das Synchronisieren der Repositories vereinfacht. Das Programm wird ebenfalls von Google heruntergeladen:
~$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/AndroidCustomROM/bin/repo ~# chmod +x ~/AndroidCustomROM/bin/repo
Auch dieser Pfad kann in die Pfadumgebung aufgenommen werden:
if [ -d "${HOME}/AndroidCustomROM/bin" ]; then PATH="${HOME}/AndroidCustomROM/bin:${PATH}"; fi;
Das Programm „sdat2img
“ wird dazu verwendet, um Android-Image-Datei in ein lesbares Format umzuwandeln:
~$ git clone https://github.com/xpirt/sdat2img /tmp/sdat2img ~$ mv /tmp/sdat2img/sdat2img.py ~//AndroidCustomROM/bin/
Damit die Kompilierung funktioniert, ist es erforderlich, dass die GNU Arm Embedded Toolchain auf dem System installiert sind.
Das aktuelle Archiv wird heruntergeladen und entpackt:
~$ tar xvfj gcc-arm-none-eabi-7-2017-q4-major-linux.tar.bz2 -C ~/AndroidCustomROM/bin/ gcc-arm-none-eabi-7-2017-q4-major/ gcc-arm-none-eabi-7-2017-q4-major/lib/ gcc-arm-none-eabi-7-2017-q4-major/lib/libcc1.so.0.0.0 ... gcc-arm-none-eabi-7-2017-q4-major/bin/arm-none-eabi-cpp gcc-arm-none-eabi-7-2017-q4-major/bin/arm-none-eabi-gcc-7.2.1 gcc-arm-none-eabi-7-2017-q4-major/bin/arm-none-eabi-nm
Das neu erzeugte Verzeichnis kann zur Vereinfachung noch umbenannt werden:
~$ mv -v ~/AndroidCustomROM/bin/gcc-arm-none-eabi-7-2017-q4-major ~/AndroidCustomROM/bin/gcc-arm-none-eabi '~/AndroidCustomROM/bin/gcc-arm-none-eabi-7-2017-q4-major' -> '~/AndroidCustomROM/bin/gcc-arm-none-eabi'
gcc-arm-none-eabi/bin/
“ erweitert werden. In einer realen Umgebung sollte darauf, wegen eventuellen Kompatiblitätsproblemen, verzichtet werden.
So lautet der Eintrag, wenn er in die Pfadumgebung aufgenommen werden soll:
if [ -d "${HOME}/AndroidCustomROM/bin/gcc-arm-none-eabi/bin" ]; then PATH="${HOME}/AndroidCustomROM/bin/gcc-arm-none-eabi/bin:${PATH}"; fi;
GIT meckert beim späteren Initialisieren, dass keine Mailadresse und kein Benutzer angegeben sind. Mindestens diese Informationen sollten also vorher eingegeben werden:
~$ git config --global user.email "<Mailadresse>" ~$ git config --global user.name "<Name>"
Es gibt mehrere Android-GIT-Repository, die für das Bauen eines Images (ROM) genutzt werden können. Dabei werden immer die beiden gleichen Schritte durchgeführt:
Jetzt erfolgt der Wechsel in das zuvor erstellte Arbeitsverzeichnis und die Initialisierung des Repository:
~$ cd ~/AndroidCustomROM/cm-14.1 ~$ repo init -u https://github.com/LineageOS/android.git -b cm-14.1 gpg: keybox '~/.repoconfig/gnupg/pubring.kbx' created gpg: ~/.repoconfig/gnupg/trustdb.gpg: trustdb created gpg: key 16530D5E920F5C65: public key "Repo Maintainer <repo@android.kernel.org>" imported ... * [new tag] cm-7.0.2.1 -> cm-7.0.2.1 * [new tag] cm-7.0.3 -> cm-7.0.3 * [new tag] cm-7.1.0 -> cm-7.1.0 repo has been initialized in ~/AndroidCustomROM/cm-14.1
Zur Erklärung:
-b
“ wird der Branch (hier in dem Fall „cm-14.1
“) ausgewählt
Im nächsten Schritt kann dann das Repository synchronisiert werden, was, je nach Internetanbindung, etwas dauern kann, weil mehrere Gigabyte an Daten heruntergeladen werden:
~$ repo sync -f --force-sync -j32 Fetching project platform/external/dagger2 Fetching project platform/external/vixl Fetching project LineageOS/android_packages_apps_TvSettings ... Checking out files: 100% (15774/15774), done.ut files: 16% (2540/15774) Checking out files: 100% (25/25), done. Syncing work tree: 100% (580/580), done.
Zur Erklärung:
-f –force-sync
“ ist optional-j32
“ kann, je nach Internetanbindung kleiner oder größer gesetzt werden
Die Initialisierung und Synchronisation des GIT-Repository muss für jeden Branch neu durchgeführt werden. Im Idealfall gibt es dafür ein neues Verzeichnis und die beiden Schritte werden wieder ausgeführt. Damit nicht wieder alle Repository-Daten heruntergeladen werden müssen, kann eine Referenzierung auf ein bestehendes Repository erfolgen.
Nachfolgend soll das GIT-Repository „https://github.com/LineageOS/android“ mit dem Branch „lineage-15.1
“ erstellt werden und als Referenz das Verzeichnis „~/AdroidCustomROM/cm-14.1
“ nutzen:
~$ mkdir ~/AndroidCustomROM/lineage-15.1 ~$ cd ~/AndroidCustomROM/lineage-15.1 ~$ repo init -u repo init -u https://github.com/LineageOS/android.git -b lineage-15.1 --reference=~/AndroidCustomROM/cm-14.1/
Die Synchronisation erfolgt dann wie gewohnt:
~$ repo sync -f --force-sync -j32
Im späteren Bauvorgang kann es vorkommen, dass Daten vom Android-Gerät selbst benötigt werden. Dies wird nachfolgend näher beschrieben.
Gibt es auf dem Android-Gerät bereits ein modifiziertes Betriebssystem (zum Beispiel LineageOS), können die notwendigen Daten von dort einfach extrahiert werden. Dafür muss das Gerät an den Rechner angeschlossen und folgender Befehl ausgeführt werden:
~$ cd ~/AndroidCustomROM/cm-4.1/device/samsung/klte ~$ ./extract-files.sh
Zur Erkärung:
Ist das Android-Gerät unmodifiziert, müssen die Gerätedaten manuell extrahiert werden. Dafür wird zum Beispiel ein LineageOS-Image von der Webseite benötigt. Es muss zwischen datei- und blockbasierten OTA-Images (OTA: over the air) unterschieden werden.
Bei block-basierten Images gibt es ein leeres Verzeichnis „system
“ und eine Datei „system.transfer.list
“.
Im Verzeichnis „~/AndroidCustomROM/cm-14.1
“ wird ein Unterverzeichnis „system_dump
“ erstellt und dort hinein gewechselt werden:
~$ mkdir ~/AndroidCustomROM/cm-14.1/system_dump ~$ cd ~/AndroidCustomROM/cm-14.1/system_dump
Jetzt werden die notwendigen Dateien aus dem heruntergeladenen Archiv entpackt:
~$ unzip lineage-14.1-<Version>-klte-signed.zip system.transfer.list system.new.dat
Dann wird mit Hilfe des Skriptes „sdat2img
“ die block-basierte Images so umwandelt, dass sie eingehängt werden können:
~$ python ~/AndroidCustomROM/bin/sdat2img.py system.transfer.list system.new.dat system.img
Dann ein Verzeichnis anlegen und einhängen:
~# mkdir system/ ~$ sudo mount system.img system/
Jetzt wieder zur Wurzel zurückspringen und die Dateien entpacken:
~$ cd ../system/device/samsung/klte ~$ ./extract-files.sh ~/AndroidCustomROM/cm-14.1/system_dump/
Das eingehängte Image kann wieder ausgehängt und das erstellte Verzeichnis entfernt werden:
~$ sudo umount ~/cm-14.1/system_dump/system ~$ rm -rf ~/cm-14.1/system_dump/
Bei dateibasierten OTAs gibt es ein Unterverzeichnis „system
“ innerhalb des Archives, welches auch weitere Verzeichnisse und Dateien enthält.
Im Verzeichnis „~/AndroidCustomROM/cm-14.1
“ muss ein Unterverzeichnis „system_dump
“ erstellt und dort hinein gewechselt werden.
~$ mkdir ~/AndroidCustomROM/cm-14.1/system_dump ~$ cd ~/AndroidCustomROM/cm-14.1/system_dump
Jetzt werden die notwendigen Dateien aus dem heruntergeladenen Archiv entpackt:
~$ unzip lineage-14.1-<Version>-klte-signed.zip system/*
Jetzt wieder zur Wurzel zurückspringen und die Dateien entpacken:
~$ cd ../system/device/samsung/klte ~$ ./extract-files.sh ~/AndroidCustomROM/cm-14.1/system_dump/
Das erstellte Verzeichnis kann entfernt werden:
~$ rm -rf ~/AndroidCustomROM/cm-14.1/system_dump/
Es gibt ein paar Einstellungen, welche das Bauen des Images beeinflusst und unter Umständen auch verbessert beziehungsweise beschleunigt.
Damit das Bauen beschleunigt wird, kann der Cache-Speicher erhöht werden:
~$ export USE_CCACHE=1
Diese Zeile kann auch in die Datei „~/.bashrc
“ eingetragen werden.
~# cd ~/AndroidCustomROM/cm-14.1 ~# prebuilts/misc/linux-x86/ccache/ccache -M 50G
Jack ist ein neuer JAVA-Compiler, welcher bekannt dafür ist, den Speicher zu überschreiten. Dies kann wie folgt repariert werden:
~# export ANDROID_JACK_VM_ARGS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4G"
Diese Zeile kann auch in die Datei „~/.bashrc
“ eingetragen werden.
Sollte diese Einstellung nicht helfen, kann die Datei „config.properties
“ angepasst werden:
~$ mkdir ~/.jack-server ~$ echo "jack.server.max-service=1" >> ~/.jack-server/config.properties
Sollte die Datei bereits existieren, muss der Parameter eventuell angepasst werden.
— Steffen Bornemann 29.04.2018