Kernel configuration

Use the following configuration settings as a base for an Android kernel configuration. Settings are organized into .cfg files for android-base, android-base-ARCH, and android-recommended:

  • android-base options enable core Android features and should be configured as specified by all devices.
  • android-base-ARCH options enable core Android features and should be configured as specified by all devices of architecture ARCH. Not all architectures have a corresponding file of architecture-specific required options. If your architecture doesn't have a file, it doesn't have additional architecture-specific kernel configuration requirements for Android.
  • android-recommended. These options enable advanced Android features and are optional for devices.

These configuration files are located in the kernel/configs repo. Use the set of configuration files that corresponds to the version of the kernel you are using.

For details on controls already undertaken to strengthen the kernel on your devices, see System and kernel security. For details on required settings, see the Android Compatibility Definition Document (CDD).

Generate kernel config

For devices that have a minimalist defconfig format, use the merge_config.sh script in the kernel tree to enable options:

ARCH=ARCH scripts/kconfig/merge_config.sh <...>/device_defconfig <...>/android-base.cfg <...>/android-base-ARCH.cfg <...>/android-recommended.cfg

This generates a .config file that you can use to save a new defconfig file or compile a new kernel with Android features enabled.

Additional kernel config requirements

In some cases, the platform maintainer can choose from multiple kernel features to satisfy an Android dependency. Such dependencies can't expressed in the kernel config fragment files (described above) because the format for those files doesn't support logical expressions. In Android 9 and higher, Compatibility Test Suite (CTS) and Vendor Test Suite (VTS) verify that the following requirements are satisfied:

  • CONFIG_OF=y or CONFIG_ACPI=y
  • 4.4 and 4.9 kernels have CONFIG_ANDROID_LOW_MEMORY_KILLER=y OR have both CONFIG_MEMCG=y and CONFIG_MEMCG_SWAP=y
  • CONFIG_DEBUG_RODATA=y or CONFIG_STRICT_KERNEL_RWX=y
  • CONFIG_DEBUG_SET_MODULE_RONX=y or CONFIG_STRICT_MODULE_RWX=y
  • For ARM64 only: CONFIG_ARM64_SW_TTBR0_PAN=y or CONFIG_ARM64_PAN=y

In addition, the CONFIG_INET_UDP_DIAG option must be set to y for 4.9 kernels in Android 9 and higher.

Enable USB host mode options

For USB host mode audio, enable the following options:

CONFIG_SND_USB=y
CONFIG_SND_USB_AUDIO=y
# CONFIG_USB_AUDIO is for a peripheral mode (gadget) driver

For USB host mode MIDI, enable the following option:

CONFIG_SND_USB_MIDI=y

Seccomp BPF with TSYNC

Secure Computing Berkeley Packet Filter (Seccomp BPF) is a kernel security technology that enables the creation of sandboxes that define the context in which a process may make system calls. The thread synchronization (TSYNC) feature enables the use of Seccomp BPF from multithreaded programs. This ability is limited to architectures that have Seccomp support upstream (ARM, ARM64, x86, and x86_64).

Android live-lock daemon

Android 10 includes the Android live-lock daemon (llkd), which is designed to catch and mitigate kernel deadlocks. For details on using the llkd, refer to Android live-lock daemon.

vDSO32 on ARM64

Virtual dynamic shared object (vDSO) is an alternative to system calls that, when used and configured correctly, can reduce cycle costs. Android 10 adds support for vDSO32 on 64-bit kernels (Android already supports vDSO64 on 64-bit kernels and vDSO32 on 32-bit kernels). Using vDSO32 (CONFIG_VDSO_COMPAT) on ARM64 architecture provides a 0.4 percent increase in battery life and other performance improvements.

The Linux community is actively working on unifying vDSOs across architectures. You can set up vDSO in your Linux kernel by enabling vDSO32 with CONFIG_COMPAT and CONFIG_CROSS_COMPILE_COMPAT_VDSO with the arm32 compiler triplet. The Android Kernel team has backported older versions of the vDSO patch series into Pixel devices, so you can find examples in Pixel kernel builds (LINUX_FCC_CROSS_COMPILE_ARM32_PREBUILTS_BIN path, CROSS_COMPILE_ARM32 reference, and CONFIG_CROSS_COMPILE_ARM32 config).

Low RAM configuration

Tune kernel and ActivityManager to reduce direct reclaim

Direct reclaim happens when a process or the kernel tries to allocate a page of memory (either directly or due to faulting in a new page) and the kernel has used all available free memory. This requires the kernel to block the allocation while it frees up a page. This in turn often requires disk I/O to flush out a dirty file-backed page or wait for lowmemorykiller to stop a process. This can result in extra I/O in any thread, including a UI thread.

To avoid direct reclaim, the kernel has watermarks that trigger kswapd or background reclaim. This is a thread that tries to free-up pages so the next time a real thread allocates, it can succeed quickly.

The default threshold to trigger background reclaim is fairly low, around 2 MB on a 2 GB device and 636 KB on a 512 MB device. The kernel reclaims only a few megabytes of memory in background reclaim. This means any process that quickly allocates more than a few megabytes is going to quickly hit direct reclaim.

Support for a kernel tunable is added in the Android-3.4 kernel branch as patch 92189d47f66c67e5fd92eafaa287e153197a454f ("add extra free kbytes tunable"). Cherry-picking this patch to a device's kernel allows ActivityManager to tell the kernel to try to keep three full-screen 32 bpp buffers of memory free.

These thresholds can be configured with the config.xml framework.

<!-- Device configuration setting the /proc/sys/vm/extra_free_kbytes tunable
in the kernel (if it exists). A high value increases the amount of memory
that the kernel tries to keep free, reducing allocation time and causing the
lowmemorykiller to kill earlier. A low value allows more memory to be used by
processes but may cause more allocations to block waiting on disk I/O or
lowmemorykiller. Overrides the default value chosen by ActivityManager based
on screen size. 0 prevents keeping any extra memory over what the kernel keeps
by default. -1 keeps the default. -->
<integer name="config_extraFreeKbytesAbsolute">-1</integer>
<!-- Device configuration adjusting the /proc/sys/vm/extra_free_kbytes
tunable in the kernel (if it exists). 0 uses the default value chosen by
ActivityManager. A positive value increases the amount of memory that the
kernel tries to keep free, reducing allocation time and causing the
lowmemorykiller to kill earlier. A negative value allows more memory to be
used by processes but may cause more allocations to block waiting on disk I/O
or lowmemorykiller. Directly added to the default value chosen by
ActivityManager based on screen size. -->
<integer name="config_extraFreeKbytesAdjust">0</integer>

Tune LowMemoryKiller

ActivityManager configures the thresholds of the LowMemoryKiller to match its expectation of the working set of file-backed pages (cached pages) required to run the processes in each priority level bucket. If a device has high requirements for the working set, for example if the vendor UI requires more memory or if more services have been added, the thresholds can be increased.

The thresholds can be reduced if too much memory is being reserved for file-backed pages, so that background processes are being killed long before disk thrashing would occur due to the cache getting too small.

<!-- Device configuration setting the minfree tunable in the lowmemorykiller
in the kernel. A high value causes the lowmemorykiller to fire earlier,
keeping more memory in the file cache and preventing I/O thrashing, but
allowing fewer processes to stay in memory. A low value keeps more
processes in memory but may cause thrashing if set too low. Overrides the
default value chosen by ActivityManager based on screen size and total memory
for the largest lowmemorykiller bucket, and scaled proportionally to the
smaller buckets. -1 keeps the default. -->
<integer name="config_lowMemoryKillerMinFreeKbytesAbsolute">-1</integer>
<!-- Device configuration adjusting the minfree tunable in the
lowmemorykiller in the kernel. A high value causes the lowmemorykiller to
fire earlier, keeping more memory in the file cache and preventing I/O
thrashing, but allowing fewer processes to stay in memory. A low value
keeps more processes in memory but may cause thrashing if set too low. Directly
added to the default value chosen by ActivityManager based on screen
size and total memory for the largest lowmemorykiller bucket, and scaled
proportionally to the smaller buckets. 0 keeps the default. -->
<integer name="config_lowMemoryKillerMinFreeKbytesAdjust">0</integer>