[Android Q&A, Help & Troubleshooting] humjam:
Hi All,

I am trying to compile a driver as a loadable module but whenever I adb shell into my phone and do an insmod test.ko I get the error message insmod: failed to load /data/local/tmp/test.ko: Exec format error. Grep'ing dmesg I find the following log: test: no symbol version for module_layout`.

I've done quite a bit of googling and reading the linux kbuild documentation txt files to no avail, so if someone knows the answer it'd be fab :)

What I've done so far is this:

I have an Qualcomm Aurora checkout and in the kernel directory I type the following

cp arch/arm64/configs/gemini_user_defconfig .config [B]# Has CONFIG_MODVERSIONS enabled[/B]
yes "" | make oldconfig ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- V=1
make prepare ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- V=1
make scripts ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- V=1
make modules ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- V=1

I have my PATH set to point to /MyAOSBDir/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin so I pick up the correct toolchain.

At this point appears to be well. In my kernel directory I have Module.symvers, so I appear to be set.

Now to the directory I have set up outside of this build tree with a dummy test... The Makefile looks like this:

KERNEL_DIR:=/solomon-build/MiNote2AOSB/kernel/
obj-m += test.o
PWD := $(shell pwd)

.PHONY: all
all:
$(MAKE) M=$(PWD) ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- -C $(KERNEL_DIR) modules V=1
clean:
$(MAKE) M=$(PWD) -C $(KERNEL_DIR) clean

The driver is just a dummy:

#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
static int __init hello_start(void)
{
printk(KERN_INFO "Hello world\n");
return 0;
}
static void __exit hello_end(void)
{
printk(KERN_INFO "Goodbye world\n");
}
module_init(hello_start);
module_exit(hello_end);

I do make "make all" at the comment line and get this output:

make M=/solomon-build/build_mxt_kmod ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- -C /solomon-build/MiNote2AOSB/kernel/ modules V=1
make[1]: Entering directory `/solomon-build/MiNote2AOSB/kernel'
test -e include/generated/autoconf.h -a -e include/config/auto.conf || ( \
echo >&2; \
echo >&2 " ERROR: Kernel configuration is invalid."; \
echo >&2 " include/generated/autoconf.h or include/config/auto.conf are missing.";\
echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \
echo >&2 ; \
/bin/false)
mkdir -p /solomon-build/build_mxt_kmod/.tmp_versions ; rm -f /solomon-build/build_mxt_kmod/.tmp_versions/*
make -f ./scripts/Makefile.build obj=/solomon-build/build_mxt_kmod
./scripts/gcc-wrapper.py aarch64-linux-android-gcc -Wp,-MD,/solomon-build/build_mxt_kmod/.test.o.d -nostdinc -isystem /solomon-build/MiNote2AOSB/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/../lib/gcc/aarch64-linux-android/4.9.x-google/include -I./arch/arm64/include -Iarch/arm64/include/generated -Iinclude -I./arch/arm64/include/uapi -Iarch/arm64/include/generated/uapi -I./include/uapi -Iinclude/generated/uapi -include ./include/linux/kconfig.h -D__KERNEL__ -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -mgeneral-regs-only -fno-pic -fno-delete-null-pointer-checks -Os -Wno-maybe-uninitialized --param=allow-store-data-races=0 -Wframe-larger-than=2048 -fstack-protector -Wno-unused-but-set-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -DMODULE -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(test)" -D"KBUILD_MODNAME=KBUILD_STR(test)" -c -o /solomon-build/build_mxt_kmod/.tmp_test.o /solomon-build/build_mxt_kmod/test.c
(cat /dev/null; echo kernel//solomon-build/build_mxt_kmod/test.ko;) > /solomon-build/build_mxt_kmod/modules.order
make -f ./scripts/Makefile.modpost
find /solomon-build/build_mxt_kmod/.tmp_versions -name '*.mod' | xargs -r grep -h '\.ko$' | sort -u | sed 's/\.ko$/.o/' | scripts/mod/modpost -m -i ./Module.symvers -I /solomon-build/build_mxt_kmod/Module.symvers -o /solomon-build/build_mxt_kmod/Module.symvers -S -E -w -s -T -
./scripts/gcc-wrapper.py aarch64-linux-android-gcc -Wp,-MD,/solomon-build/build_mxt_kmod/.test.mod.o.d -nostdinc -isystem /solomon-build/MiNote2AOSB/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/../lib/gcc/aarch64-linux-android/4.9.x-google/include -I./arch/arm64/include -Iarch/arm64/include/generated -Iinclude -I./arch/arm64/include/uapi -Iarch/arm64/include/generated/uapi -I./include/uapi -Iinclude/generated/uapi -include ./include/linux/kconfig.h -D__KERNEL__ -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -mgeneral-regs-only -fno-pic -fno-delete-null-pointer-checks -Os -Wno-maybe-uninitialized --param=allow-store-data-races=0 -Wframe-larger-than=2048 -fstack-protector -Wno-unused-but-set-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(test.mod)" -D"KBUILD_MODNAME=KBUILD_STR(test)" -DMODULE -c -o /solomon-build/build_mxt_kmod/test.mod.o /solomon-build/build_mxt_kmod/test.mod.c
aarch64-linux-android-ld -EL -r -T ./scripts/module-common.lds --build-id --fix-cortex-a53-843419 -o /solomon-build/build_mxt_kmod/test.ko /solomon-build/build_mxt_kmod/test.o /solomon-build/build_mxt_kmod/test.mod.o
make[1]: Leaving directory `/solomon-build/MiNote2AOSB/kernel'

So, there are no messages saying there is a missing Module.symvers, so that's good, and I do get a built .ko file.

What I don't understand is the message "ERROR: Kernel configuration is invalid". The files it is talking about exist, so I know they have been created in my kernel build.

Anyway, trying to insmod this onto the phone gives the message I mentioned previously. If I cat Module.symvers I see:

0xff924338 backlight_force_update drivers/video/backlight/backlight EXPORT_SYMBOL
0x30254daf test_iosched_register block/test-iosched EXPORT_SYMBOL
<snip>
0xdd502540 backlight_device_unregister drivers/video/backlight/backlight EXPORT_SYMBOL
0x9939eba0 backlight_unregister_notifier drivers/video/backlight/backlight EXPORT_SYMBOL

So no symbol module_layout in the file, and thus no CRC, which is what I presume is creating the error message?

Any clues would be much appreciated, thank you.

Oh I should also mention that the module and kernel vermagic match:

# modinfo /data/local/tmp/test.ko
filename: /data/local/tmp/test.ko
depends:
vermagic: 3.18.20-mytestkernel-perf-g671c431-dirty SMP preempt mod_unload modversions aarch64

# uname -a
Linux localhost 3.18.20-mytestkernel-perf-g671c431-dirty #1 SMP PREEMPT Mon Jun 5 15:46:13 BST 2017 aarch64