Android goldfish armv7 kernel module compiling - android

I have compiled goldfish armv7 kernel for android.
everything works well, my compiled kernel works fine on the emulator.
my problem is, I want to insert a kernel module(.ko) into my goldfish kernel.
but cross compiling the 'hello world' kernel module gives me some error.
so I googled it and found out that I need to recompile my goldfish kernel with
'CONFIG_MODULES=y'
option enabled.
as I read on the Internet, I added the following lines to my .config script.
CONFIG_MODULES=y
CONFIG_MODULES_FORCE_LOAD=y
CONFIG_MODULES_UNLOAD=y
CONFIG_MODULES_FORCE_UNLOAD=y
But if I recompile my goldfish kernel with these options, I get the following error.
LD net/built-in.o
LD vmlinux.o
MODPOST vmlinux.o
GEN .version
CHK include/generated/compile.h
UPD include/generated/compile.h
CC init/version.o
LD init/built-in.o
LD .tmp_vmlinux1
net/built-in.o: In function `tcp_nuke_addr':
activity_stats.c:(.text+0x4e4b4): undefined reference to `rt6_lookup'
activity_stats.c:(.text+0x4e5c4): undefined reference to `in6addr_any'
make: *** [.tmp_vmlinux1] Error 1
root#ubuntu:/disk2/android/kernel/goldfish#
some of the documentation says that I should remove the CONFIG_NETFILTER=y from the script.
I did it but the result is same.
I am stuck right now... can someone help me??
thank you in advance.

There is a suggested list of Linux configuration options at https://source.android.com/devices/tech/kernel.html including CONFIG_NETFILTER.

i removed all the configurations to do with IPV6, INET6
Remember to disable only IPV6 related modules and not the IPv4.
# CONFIG_IPV6 is not set
After that I was able to build it.

Also works
CONFIG_IPV6=y
It seems that build try to configure IPv6 as a module, but there are functions used by kernel that not are available if IPv6 is not built-in in the kernel

Related

How do you update the GNU linker for an Android NDK?

I am working on a native Android project using NDK r12b. This NDK (and it looks like all others since) ships with a prebuilt GNU linker version 2.25. We have recently tried to pull up lots of our project's submodules which has introduced a build error that looks like it is caused by this bug in ld.
build error output:
/opt/android-ndk-r12b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: internal error in do_relocate_sections, at /usr/local/google/buildbot/src/android/gcc/toolchain/build/../binutils/binutils-2.25/gold/reloc.cc:953
collect2: error: ld returned 1 exit status
I thought I would attempt to update the linker but have had no luck finding prebuilt binaries. So I went down the rabbit hole of trying to compile ld/binutils myself. Either my Google skills are failing me, or documentation for doing this is truly rare or presumes the user has a lot of introductory knowledge that I don't have.
When building binutils 2.29.1 with target=arm-linux my application build errors out with this result:
/opt/android-ndk-r12b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: unrecognised emulation mode: armelf_linux_eabi
Supported emulations: armelf_linux armelf armelfb armelfb_linux
collect2: error: ld returned 1 exit status
For reference, the -V output of our current version of ld is:
me#linux-vm:/opt/android-ndk-r12b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/arm-linux-androideabi/bin$ ./ld-2.25 -V
GNU gold (binutils-2.25-0666073 2.25.51.20141117) 1.11
Supported targets:
elf64-littleaarch64
elf64-bigaarch64
elf32-littleaarch64
elf32-bigaarch64
elf64-tradlittlemips
elf32-tradlittlemips-nacl
elf64-tradbigmips
elf32-tradlittlemips-nacl
elf32-tradlittlemips
elf32-tradlittlemips-nacl
elf32-tradbigmips
elf32-tradlittlemips-nacl
elf32-tilegx-be
elf64-tilegx-be
elf32-tilegx-le
elf64-tilegx-le
elf32-bigarm
elf32-bigarm-nacl
elf32-littlearm
elf32-littlearm-nacl
elf64-powerpcle
elf64-powerpc
elf32-powerpcle
elf32-powerpc
elf64-sparc
elf32-sparc
elf32-x86-64
elf32-x86-64-freebsd
elf32-x86-64-nacl
elf64-x86-64
elf64-x86-64-freebsd
elf64-x86-64-nacl
elf32-i386
elf32-i386-freebsd
elf32-i386-nacl
Supported emulations:
aarch64_elf64_le_vec
aarch64_elf64_be_vec
aarch64_elf32_le_vec
aarch64_elf32_be_vec
elf64-tradlittlemips
elf32-tradlittlemips-nacl
elf64-tradbigmips
elf32-tradlittlemips-nacl
elf32-tradlittlemips
elf32-tradlittlemips-nacl
elf32-tradbigmips
elf32-tradlittlemips-nacl
elf32tilegx_be
elf64tilegx_be
elf32tilegx
elf64tilegx
armelfb
armelfb_nacl
armelf
armelf_nacl
elf64lppc
elf64ppc
elf32lppc
elf32ppc
elf64_sparc
elf32_sparc
elf32_x86_64
elf32_x86_64_nacl
elf_x86_64
elf_x86_64_nacl
elf_i386
elf_i386_nacl
So apparently I'm missing some important configuration parameters. I also tried using an older (r8e) Android NDK's build/tools/build-gcc.sh script to build the entire compiler toolchain but with a newer binutils version. This resulted in an unknown build error:
me#linux-vm:/opt/android-ndk-r8e/build/tools$ ./build-gcc.sh --gmp-version=5.0.5 --mpfr-version=3.1.1 --mpc-version=1.0.1 --binutils-version=2.26
$(pwd)/src $(pwd) arm-linux-androideabi-4.7
To follow build in another terminal, please use: tail -F /tmp/ndk-me/build/toolchain/config.log
Using C compiler: gcc -m32
Using C++ compiler: g++ -m32
Sysroot : Copying: /opt/android-ndk-r8e/platforms/android-9/arch-arm --> /tmp/ndk-me/build/toolchain/prefix/sysroot
Configure: arm-linux-androideabi-4.7 toolchain build
Building : arm-linux-androideabi-4.7 toolchain [this can take a long time].
Error while building toolchain. See /tmp/ndk-me/build/toolchain/config.log
Last entries of config.log:
ar cru libintl.a bindtextdom.o dcgettext.o dgettext.o gettext.o finddomain.o loadmsgcat.o localealias.o textdomain.o l10nflist.o explodename.o dcigettext.o dcngettext.o dngettext.o ngettext.o plural.o plural-exp.o localcharset.o relocatable.o localename.o log.o osdep.o intl-compat.o
ranlib libintl.a
make[1]: Leaving directory `/tmp/ndk-me/build/toolchain/libbfd-binutils-2.26/intl'
At this point I'm just spinning my tires and trying to brute force success with different combinations of configuration parameters and source package versions. It seems as simple as adding emulation support for armelf_linux_eabi, but like I said, I have failed to find any documentation or guides that show how to do this. Surely there is a GNU wizard out there somewhere who could point me down a better path? Any help is appreciated!
I would try --enable-targets=all first. It is a bit of a big hammer, but maybe it helps you to avoid figuring out the exact target triplets you need (my guess would be arm-unknown-linux-eabi).

Error while trying to compile android kernel in ubuntu

I'm trying to compile a Android Kernel from source and I have downloaded all the right packages to do it but for some reason I get this error:
arm-linux-androideabi-gcc: error: unrecognized command line option '-mgeneral-regs-only'
/home/livlogik/android/kernel/H901BK_L_Kernel/./Kbuild:35: recipe for target 'kernel/bounds.s' failed
make[1]: *** [kernel/bounds.s] Error 1
Makefile:858: recipe for target 'prepare0' failed
make: *** [prepare0] Error 2
I have the latest NDK and I'm using Ubuntu 15.10 64bit if this helps.
Here is where I have the NDK and kernel:
NDK ---- /home/livlogik/android/ndk/
Kernel ---- /home/livlogik/android/kernel/H901bk_L_Kernel/
If someone could help me that would be great. Sorry if this was already posted I could find a answer to it.
Thanks,
Zach
As it can be seen from build error message:
drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c:20:27: fatal error: ./mh1/msm_mh1.h: No such file or directory
#include <./mh1/msm_mh1.h>
compiler just can't find msm_mh1.h file. This is because the path specified for #include directive isn't correct. Most probably it's typo: instead ./ there should be ../.
To fix that error, in drivers/media/platform/msm/camera_v2/sensor/msm_sensor.c file change this line:
#include <./mh1/msm_mh1.h>
to this line
#include "../mh1/msm_mh1.h"
After this make command should work fine. Also, kernel image file will be available at arch/arm64/boot, and it's not zImage as stated in documentation, it's actually Image.gz. Uncompressed kernel image is Image file.
Update
Answering your question in comments:
Is there any way to make it compress into a zImage?
From Documentation/arm64/booting.txt:
The AArch64 kernel does not currently provide a decompressor and
therefore requires decompression (gzip etc.) to be performed by the boot
loader if a compressed Image target (e.g. Image.gz) is used. For
bootloaders that do not implement this requirement, the uncompressed
Image target is available instead.
Basically zImage is just gzipped and self-extracted Image. So zImage file consists of program for unpacking gzip archive in the beginning, followed by gzipped Image, and when kernel is run by bootloader its unpacking itself (hense "self-extracted" term) and then start running.
...So I can make it flashable
In case of arm64, you don't have zImage, so most likely you need to use Image file (which acts in the same way, but only its size is bigger). You can create boot.img from Image file and built AFS ramdisk (using mkbootimg tool) and then just do fastboot flash boot boot.img. Refer to this documentation for example. Of course for your platform some things can be different, so try to find instructions for your platform.
You have to install the right toolchain:
git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9
And configure the Makefile appropriately
The wrong toolchain is at
git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/arm/arm-linux-android-4.9

'elf.h' file not found error when compiling Android kernel for Nexus 7 on Mac OS X

When compiling Android kernel for Nexus 7 on Mountain Lion 10.8.4 I ran into fatal error: 'elf.h' file not found issue:
/Volumes/Android/WORKING_DIRECTORY/device/asus/grouper/tegra/
[derek#retina-mbp]$ make
scripts/kconfig/conf --silentoldconfig Kconfig
CHK include/linux/version.h
UPD include/linux/version.h
CHK include/generated/utsrelease.h
UPD include/generated/utsrelease.h
Generating include/generated/mach-types.h
CC kernel/bounds.s
GEN include/generated/bounds.h
CC arch/arm/kernel/asm-offsets.s
GEN include/generated/asm-offsets.h
CALL scripts/checksyscalls.sh
CC scripts/mod/empty.o
HOSTCC scripts/mod/mk_elfconfig
scripts/mod/mk_elfconfig.c:4:10: fatal error: 'elf.h' file not found
#include <elf.h>
^
1 error generated.
make[2]: *** [scripts/mod/mk_elfconfig] Error 1
make[1]: *** [scripts/mod] Error 2
make: *** [scripts] Error 2
Does anyone know how to fix this so that the kernel compilation can continue?
I'm answering my own question because I found workaround for the missing elf.h file:
cd /Volumes/Android/WORKING_DIRECTORY/external/elfutils/libelf/
$ sudo cp -a elf.h /usr/include
With a copy of 'elf.h' file now in /usr/include the compilation goes on for a while, but then stops again with a different error:
arch/arm/mach-tegra/sleep.S: Assembler messages:
arch/arm/mach-tegra/sleep.S:240: Error: selected processor does not support ARM mode `smc #0'
make[1]: *** [arch/arm/mach-tegra/sleep.o] Error 1
make: *** [arch/arm/mach-tegra] Error 2
Not sure what to do about this last error though.
UPDATE: I gave up on trying to compile Android kernel directly under OS X. Instead, I installed 64-bit Ubuntu on VirtualBox and followed instructions found on this page:
http://forum.xda-developers.com/showthread.php?t=1774035
Except that as I said, I used VirtualBox and not VMWare Player as the above page suggested. It worked great and I didn't have any problems with networking and was able to ssh into Ubuntu to easily move compiled kernel back to OS X.
I also referred to this page to get the right kernel source for my device (grouper), prebuilt gcc and syntax for the make command (make tegra3_android_defconfig):
http://source.android.com/source/building-kernels.html
I hope this answer will save someone some time.
if you are still interested, check this out http://algobardo.github.io/2014/10/Android-Kernel-MacOsX/ and let me know if it is reproducible on your system with your android version.

Building kernel module for Android

I need to add the FTDI USB module to the Android kernel (Android 2.3.1, Linux 2.6.32), so I got the 2.6.32 kernel and tried to build the module:
make modules ARCH=arm CROSS_COMPILE=arm-none-eabi-
But when I tried to do 'insmod ftdi_sio.ko', the error message was
insmod: init_module 'ftdi_sio.ko' failed (Exec format error)
In dmesg's output I found this
ftdi_sio: version magic '2.6.32.27 preempt mod_unload ARMv5 ' should be '2.6.32.27 preempt mod_unload ARMv7 '
I tried to add 'armv7-a' flag (as I read in Android NDK docs)
make modules ARCH=arm CROSS_COMPILE=arm-linux-androideabi- CFLAGS='-march=armv7-a -mfloat-abi=softfp'
Also, I tried following cross-compilers: arm-none-eabi-, arm-eabi-, arm-linux-android-eabi-
Every time result was the same - ARMv5 in the version magic.
How can I build the module for ARMv7?
Try setting up CONFIG_CPU_V7=y in your kernel .config file

Loading kernel module in Android kernel

I am listing my problem here.
I have a Google Nexus one a.k.a. "passion" phone with me. Fastboot and adb tools are installed in the phone. And the boot loader is unlocked.
My task: I have to add a linux kernel module to the Android kernel.
What I have done:
I followed the steps in http://source.android.com/source/initializing.html and downloaded the kernel for android-2.3.6_r1 (passion) and have built it. I am also able to flash it on the phone and the new android kernel also works fine. Now what I want is to modify the kernel and add my own kernel module and then flash it on the phone, so that the kernel on the phone is my modified kernel.
Now I have come across two approaches to do this.
1)
Cross Compile my kernel module with the android kernel and push it on the device with adb command. The Makefile I use in the kernel is as follows.
VERSION = 2
PATCHLEVEL = 3
SUBLEVEL = 6
EXTRAVERSION = -00054-g5f01537
obj-m += hello-1.o
KDIR=/home/apurva/android_dir
PWD := $(shell pwd)
all:
make -C $(KDIR) ARCH=arm CROSS_COMPILE=/home/apurva/android_dir/prebuilt/linux- x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- SUBDIRS=$(PWD) modules
clean:
make -C $(KDIR) ARCH=arm CROSS_COMPILE=/home/apurva/android_dir/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi- SUBDIRS=$(PWD) clean
Now this is not able to generate new hello-1.ko. I do not know why, I guess there is some problem with the VERSION, PATCHLEVEL, SUBLEVEL and EXTRAVERSION values. Are these necessary? I tried these value from android-2.3.6_r1 also but still it does not work. I am not sure what is this EXTRAVERSION value?
I even tried with the hello-1.ko generated from the compiler in my ubuntu. I pushed this hello-1.ko into the emulator with the following adb command.
/root/bin/src/out/host/linux-x86/bin/adb shell mount
/root/bin/src/out/host/linux-x86/bin/adb push hello-1.ko /data
/root/bin/src/out/host/linux-x86/bin/adb insmod /data/hello-1.ko
But that hello-1.ko is not able to insmod and I get the following error.
insmod : Error in init_module() hello-1.ko function not implemented
Whereas the hello-1.c is quite simple:
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
int init_module(void)
{
printk(KERN_INFO "Hello world 1.\n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Goodbye world 1.\n");
}
2)
The second approach of doing this can be placing my source files of the kernel module in the kernel directory of android. May be in the system directory or somewhere else and ask the make to build these source files also along with the other source. But I am not sure where to ask the make process to do so. I tried to do so in main.mk and created a Android.mk file in the source directory of my source files but it did not work. May be this is a better solution but I could not find any help on this.
After doing this, my kernel modules should be able to control the wnic (Wireless Network Interface device) of the android phone. It should be able to put the wnic in sleep mode and then wake it up after receiving command from my kernel module. If you have some pointers on how to do this, that will be a help. I have found that on Android it is controlled through wpa_supplicant private driver. Commands, like:
wpa_cli driver powermode 0 - auto
wpa_cli driver powermode 1 - active
can do my task, but I am not sure since I have not tried. I have not reached that stage.
Please look into this and provide some help/guidance.
Thanks,
Apurva
Kernel modules (KO's) are much easier to work with than a static kernel - as long as the kernel has enabled them. The easiest way to tell is do an "adb shell lsmod". Second is to see if the kernel .config has enabled CONFIG_MODULES=y and CONFIG_MODULE_UNLOAD=y. Lots of info on the web about linux KO development.
Hummm, you're close but it looks like the makefile is screwy. First try to build the hello KO on your host for unit test, then build on your target. Here's a sample makefile I use on an OMAP36xx running gingerbread:
# Makefile for trivial android kernel module
obj-m += mod_hello.o
CROSS_COMPILE=/opt/distros/ARM/bin/arm-none-linux-gnueabi-
TARG_KDIR ?= /opt/android/dal/nook_kernel
HOST_KDIR=/lib/modules/$(shell uname -r)/build
# target creates:
# .<obj>.o: CC command line for the .o, including dependencies
# .<obj>.mod.o.cmd: CC command line for the mod.o, including dependencies
# .<obj>.ko.cmd: LD command line which links the .o and .mod.o to create the .ko
target:
#echo "Make module for target arm"
make -C $(TARG_KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) modules
host:
#echo "Make module for host"
make -C $(HOST_KDIR) M=$(PWD) modules
clean:
#echo "cleaning target"
make -C $(TARG_KDIR) M=$(PWD) clean
#echo "cleaning host"
make -C $(HOST_KDIR) M=$(PWD) clean
First check in the .config if the module support is enabled. (CONFIG_MODULES=y and CONFIG_MODULE_UNLOAD=y) if not enable them using menuconfig.
Then place your module on the root of the kernel source and add this to the main makefile you find at the root
core-y := usr/ yourModule/
and this to the yourModule folders makefile
obj-m := yourModule.o

Categories

Resources