Background
Recently, I noticed that the upstream LineageOS kernel source for the Sony sm8250 platform was preparing to update to version 23.0 (i.e., Android 16, the successor to the current lineage-22.2 branch). Consequently, the Droidian device kernel also needed to be updated. After merging the changes, I discovered that the upstream had switched to defconfig fragments. This means it no longer relies on a single pdx206_defconfig
file for configuration.
Initially, I tried to manually merge the multiple fragment files using the old single-configuration-file approach, but this led to a series of compilation issues, such as the device tree blob (dtb) not being generated and missing BPF function definitions. Subsequent investigation revealed conflicts in my manually merged configuration. For instance, one fragment contained # CONFIG_MACH_SONY_PDX206 is not set
, while the vendor/pdx206.config
file that defines this config was included earlier. Unexpectedly, this overrode the required CONFIG_MACH_SONY_PDX206=y
setting (similar to the SYSVIPC configuration issue encountered by Lindroid: https://t.me/linux_on_droid/1263).
Due to these issues, I had to completely rewrite the configuration and revisit the Droidian linux-packaging-snippets
configuration scripts. Since these details might not be explicitly covered in the official documentation, I decided to systematically document this troubleshooting experience.
Kernel Config Merging Logic
The logic for this is defined in /usr/share/linux-packaging-snippets/kernel-snippet.mk
, which can be examined in the official Droidian Docker build image (quay.io/droidian/build-essential
). The final kernel .config
file is generated by concatenating multiple configuration fragments defined in debian/kernel-info.mk
. The order of the configuration files determines their priority; later fragments can override settings from earlier ones. Ultimately, the final value of a configuration option is determined by the last fragment that sets it. For example, if Fragment A sets CONFIG_X=y
and Fragment B sets # CONFIG_X is not set
, the final result will be CONFIG_X
not being enabled.
The main configuration parameters used are (listed in the actual concatenation order):
KERNEL_DEFCONFIG
: The default defconfig to use. This practically uses$(KERNEL_SOURCES)/arch/$(KERNEL_ARCH)/configs/$(KERNEL_DEFCONFIG)
.KERNEL_CONFIG_COMMON_FRAGMENTS
: Common kernel configuration fragments typically used for Droidian kernels. Usually doesn’t require manual configuration; it defaults to include$(KERNEL_SOURCES)/droidian/common_fragments/halium.config
and$(KERNEL_SOURCES)/droidian/common_fragments/droidian.config
.KERNEL_CONFIG_DEVICE_FRAGMENTS
: Device-specific configuration fragments. Files are included in the order specified by the following variables:DEVICE_PLATFORM
: Use$(KERNEL_SOURCES)/droidian/$(DEVICE_PLATFORM).config
DEVICE_MODEL
: Use$(KERNEL_SOURCES)/droidian/$(DEVICE_MODEL).config
KERNEL_CONFIG_EXTRA_FRAGMENTS
: Additional fragment configuration files to be added, which must be placed under$(KERNEL_SOURCES)/droidian/
. Multiple-files is supported.
How to Find the Kernel Configuration Files for Your Device
This explanation is based on the current upstream LineageOS. For other Android system upstreams, please use this as a reference only.
You typically need to look at two projects: android_device_{VENDOR}_{SOC}-common
and android_device_{VENDOR}_{MODEL}
.
For the Sony Xperia 5 II
, the VENDOR
is Sony
, and the device codename is pdx206
. Therefore, the first project to examine is android_device_sony_pdx206
. Then, look for TARGET_KERNEL_CONFIG
in BoardConfig.mk
to find the device’s kernel configuration file.
|
|
However, it usually also requires additional SoC platform kernel configuration files. This requires checking the corresponding android_device_{VENDOR}_{SOC}-common
project. You can typically find this in the device project’s lineage.dependencies
file. For example: https://github.com/LineageOS/android_device_sony_pdx206/blob/lineage-23.0/lineage.dependencies
|
|
The corresponding SoC platform project is android_device_sony_sm8250-common
. Next, you need to find the SoC kernel configuration files in this project.
The configuration file for the SoC platform project is BoardConfigCommon.mk
. Again, search for TARGET_KERNEL_CONFIG
within it to find the remaining configuration files.
|
|
Extra: How to Debug Bootloop Issues
This section addresses the bootloop situation caused by using an incorrect kernel config previously. In the past, I was helpless in such scenarios. However, I recently stumbled upon the correct debugging method and am no longer working blindly.
The problem was this: I flashed the kernel merged with the upstream updates. After rebooting, it bootlooped a few times before eventually booting into the system normally. Checking uname
showed the old kernel version. journalctl
logs contained no information from the bootloop period, only logs after the successful boot. I realized I needed to debug and collect logs from the device’s early boot stage. I subsequently found the following two methods:
ADB on Boot
One method is to enable all ADB debug connections by default at boot. Details can be found here: https://johannes.truschnigg.info/writing/2022-05_android_bootloop_debugging/. However, I couldn’t use it due to two problems:
- It requires modifying the
build.prop
configuration on the system partition. This is impossible under normal operation in Droidian because the system partition is mounted as a read-only loopback. Furthermore, thesystem
directory isn’t visible in recovery mode, making this approach unusable. - If the problem occurs during the kernel bootup phase, the system crashes before even reaching the point where
adbd
starts. In my case, the bootloop was ultimately caused by a kernel panic, making this method unsuitable.
pstore
Another method is to use pstore to preserve the kernel crash logs from the bootup phase in a persistent storage area (often RAM). Upon the next boot, you can find the kernel panic information and the crash logs in /sys/fs/pstore
. For details, refer to: https://docs.kernel.org/admin-guide/pstore-blk.html
When I tried it, possibly due to system design, the pstore area might be cleared during a normal boot, or the logs from the previous boot might not be retained in /sys/fs/pstore
by default, so the directory appeared empty. Later, I read that pstore contents might be accessible in recovery mode. I tried forcing a shutdown after a bootloop, directly entering fastboot mode, and then booting into recovery. Sure enough, I found the logs there. Finally, I saw the reason for the kernel panic during boot:
|
|
After examining the kernel code, the issue was likely related to a USB PD (Power Delivery) device. During wakeup initialization, a device information node encountered a problem, specifically a prev
null pointer during registration. Such linked list errors are typically related to kernel configuration conflicts or incorrect driver initialization. It’s essential to verify whether related configurations (like CONFIG_USB_PDPHY
) are enabled. However, I later realized the root cause was the kernel configuration approach itself. After modifying how the kernel configuration files were handled, this problem disappeared. Nonetheless, if similar issues arise in the future, this debugging approach should still be applicable.