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
orCONFIG_ACPI=y
- 4.4 and 4.9 kernels have
CONFIG_ANDROID_LOW_MEMORY_KILLER=y
OR have bothCONFIG_MEMCG=y
andCONFIG_MEMCG_SWAP=y
CONFIG_DEBUG_RODATA=y
orCONFIG_STRICT_KERNEL_RWX=y
CONFIG_DEBUG_SET_MODULE_RONX=y
orCONFIG_STRICT_MODULE_RWX=y
- For ARM64 only:
CONFIG_ARM64_SW_TTBR0_PAN=y
orCONFIG_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>