I am trying to add a linux kernel driver to the android source.
I add it in the config file to be built (kernel/msm-4.9/arch/arm64/config/sdm845_defconfig).
CONFIG_LEDS_QPNP_WLED=y
# CONFIG_LEDS_QPNP_HAPTICS is not set
CONFIG_HAPTICS_MISC=y
The makefile and Kconfig files in kernel/msm-4.9/drivers/misc/ are also updated to include the driver.
Makefile:
haptics-misc-objs := haptics-misc.o hatpics-misc-tables.o
obj-$(CONFIG_HAPTICS_MISC) += haptics-misc.o
Kconfig:
config HAPTICS_MISC
tristate "Haptics driver"
depends on I2C && SYSFS && NEW_LEDS
help
Boosted Haptics Driver
I attempt to build the kernel with the following steps:
$ source build/envsetup.sh
$ lunch 41
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=8.1.0
TARGET_PRODUCT=sdm845
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_PLATFORM_VERSION=OPM1
TARGET_BUILD_APPS=
TARGET_ARCH=arm64
TARGET_ARCH_VARIANT=armv8-a
TARGET_CPU_VARIANT=kryo300
TARGET_2ND_ARCH=arm
TARGET_2ND_ARCH_VARIANT=armv7-a-neon
TARGET_2ND_CPU_VARIANT=cortex-a9
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-4.15.0-24-generic-x86_64-with-Ubuntu-16.04-xenial
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=OPM1.171019.026
OUT_DIR=out
AUX_OS_VARIANT_LIST=
$ make -j12
The build fails with the following error:
Haptics driver (HAPTICS_MISC) [N/m/y/?] (NEW) aborted!
Console input/output is redirected. Run 'make oldconfig' to update configuration.
/media/ftreven/quarter-b/Open-Q_845_Android-O_v1.0/Source_Package/SDA845_Open-Q_845_Android-O_v1.0/kernel/msm-4.9/scripts/kconfig/Makefile:37: recipe for target 'silentoldconfig' failed
make[3]: *** [silentoldconfig] Error 1
/media/ftreven/quarter-b/Open-Q_845_Android-O_v1.0/Source_Package/SDA845_Open-Q_845_Android-O_v1.0/kernel/msm-4.9/Makefile:550: recipe for target 'silentoldconfig' failed
make[2]: *** [silentoldconfig] Error 2
make[1]: *** No rule to make target 'include/config/auto.conf', needed by 'include/config/kernel.release'. Stop.
make[1]: Leaving directory '/media/ftreven/quarter-b/Open-Q_845_Android-O_v1.0/Source_Package/SDA845_Open-Q_845_Android-O_v1.0/out/target/product/sdm845/obj/kernel/msm-4.9'
Makefile:150: recipe for target 'sub-make' failed
make: *** [sub-make] Error 2
It seems from the error message that the command fails solely because the symbol is new. It recommends to make oldconfig but this also fails:
$ make oldconfig
ninja: error: unknown target 'oldconfig', did you mean 'fmconfig'?
13:08:18 ninja failed with: exit status 1
#### failed to build some targets (38 seconds) ####
I am uncertain what "fmconfig" is but I attempt to build it as suggested and it succeeds. However, attempting to build the whole kernel fails for the same reason as above. Any idea what could be causing this? It was built successfully prior to adding the new symbol.
I discovered that after Linux kernel version 4.9 was released, the android framework stopped allowing built-in drivers. To get around this I had to instead build the drivers as Dynamically Loadable Kernel Modules. To do this I created a directory under vendor/ called dlkm/ where I place all source code and configs/Makefile.
After this is done I can build the source successfully.
$ source build/envsetup.sh
$ lunch 41
$ make -j12
#### build completed successfully (03:38 (mm:ss)) ###
There can be no reference to the driver in the actual kernel part of the android framework or the build will fail. The exception to this is for device trees (.dtsi, .dts files) which will still be built within the kernel.