4 Mesa hardware drivers can be built for Android one of two ways: built
5 into the Android OS using the ndk-build build system on older versions
6 of Android, or out-of-tree using the Meson build system and the
9 The ndk-build build system has proven to be hard to maintain, as one
10 needs a built Android tree to build against, and it has never been
11 tested in CI. The Meson build system flow is frequently used by
12 Chrome OS developers for building and testing Android drivers.
14 Building using the Android NDK
15 ------------------------------
17 Download and install the NDK using whatever method you normally would.
18 Then, create your Meson cross file to use it, something like this
19 ``~/.local/share/meson/cross/android-aarch64`` file::
22 ar = 'NDKDIR/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar'
23 c = ['ccache', 'NDKDIR/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android29-clang']
24 cpp = ['ccache', 'NDKDIR/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android29-clang++', '-fno-exceptions', '-fno-unwind-tables', '-fno-asynchronous-unwind-tables', '-static-libstdc++']
27 strip = 'NDKDIR/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-strip'
28 # Android doesn't come with a pkg-config, but we need one for Meson to be happy not
29 # finding all the optional deps it looks for. Use system pkg-config pointing at a
30 # directory we get to populate with any .pc files we want to add for Android
31 pkgconfig = ['env', 'PKG_CONFIG_LIBDIR=NDKDIR/pkgconfig', '/usr/bin/pkg-config']
39 Now, use that cross file for your Android build directory (as in this
40 one cross-compiling the turnip driver for a stock Pixel phone)
42 .. code-block:: console
44 meson build-android-aarch64 \
45 --cross-file android-aarch64 \
47 -Dplatform-sdk-version=26 \
50 -Dvulkan-drivers=freedreno \
52 ninja -C build-android-aarch64
54 Replacing Android drivers on stock Android
55 ------------------------------------------
57 The vendor partition with the drivers is normally mounted from a
58 read-only disk image on ``/vendor``. To be able to replace them for
59 driver development, we need to unlock the device and remount
60 ``/vendor`` read/write.
62 .. code-block:: console
68 Now you can replace drivers as in:
70 .. code-block:: console
72 adb push build-android-aarch64/src/freedreno/vulkan/libvulkan_freedreno.so /vendor/lib64/hw/vulkan.sdm710.so
74 Note this command doesn't quite work because libvulkan wants the
75 SONAME to match. For now, in turnip we have been using a hack to the
76 meson.build to change the SONAME.
78 Replacing Android drivers on Chrome OS
79 --------------------------------------
81 Chrome OS's ARC++ is an Android container with hardware drivers inside
82 of it. The vendor partition with the drivers is normally mounted from
83 a read-only squashfs image on disk. For doing rapid driver
84 development, you don't want to regenerate that image. So, we'll take
85 the existing squashfs image, copy it out on the host, and then use a
86 bind mount instead of a loopback mount so we can update our drivers
87 using scp from outside the container.
89 On your device, you'll want to make ``/`` read-write. ssh in as root
92 .. code-block:: console
94 crossystem dev_boot_signed_only=0
95 /usr/share/vboot/bin/make_dev_ssd.sh --remove_rootfs_verification --partitions 4
98 Then, we'll switch Android from using an image for ``/vendor`` to using a
99 bind-mount from a directory we control.
101 .. code-block:: console
103 cd /opt/google/containers/android/
105 mount -o loop vendor.raw.img vendor-ro
106 cp -a vendor-ro vendor-rw
109 In the ``config.json``, you want to find the block for ``/vendor`` and
113 "destination": "/vendor",
115 "source": "/opt/google/containers/android/vendor-rw",
122 Now, restart the UI to do a full reload:
124 .. code-block:: console
128 At this point, your android container is restarted with your new
129 bind-mount ``/vendor``, and if you use ``android-sh`` to shell into it
130 then the ``mount`` command should show::
132 /dev/root on /vendor type ext2 (rw,seclabel,relatime)
134 Now, replacing your DRI driver with a new one built for Android should
137 .. code-block:: console
139 scp msm_dri.so $HOST:/opt/google/containers/android/vendor-rw/lib64/dri/
141 You can do your build of your DRI driver using ``emerge-$BOARD
142 arc-mesa-freedreno`` (for example) if you have a source tree with
143 ARC++, but it should also be possible to build using the NDK as
144 described above. There are currently rough edges with this, for
145 example the build will require that you have your arc-libdrm build
146 available to the NDK, assuming you're building anything but the
147 Freedreno Vulkan driver for KGSL. You can mostly put things in place
150 .. code-block:: console
152 scp $HOST:/opt/google/containers/android/vendor-rw/lib64/libdrm.so \
153 NDKDIR/sysroot/usr/lib/aarch64-linux-android/lib/
156 /usr/include/xf86drm.h \
157 /usr/include/libsync.h \
158 /usr/include/libdrm \
159 NDKDIR/sysroot/usr/include/
161 It seems that new invocations of an application will often reload the
162 DRI driver, but depending on the component you're working on you may
163 find you need to reload the whole Android container. To do so without
164 having to log in to Chrome again every time, you can just kill the
165 container and let it restart:
167 .. code-block:: console
169 kill $(cat /run/containers/android-run_oci/container.pid )