-
Notifications
You must be signed in to change notification settings - Fork 7
Serval on Android
These instructions have been tested for a Nexus One device, but should with small modifications work for other devices. When targeting a different device, it might be necessary to use a different NDK, compiler, kernel source tree, etc.
- Kernel source code matching your cross-compile environment (see instructions below).
- Android NDK: http://developer.android.com/sdk/ndk/index.html (r5c is known to work for Nexus One).
- Android SDK: http://developer.android.com/sdk/index.html with "Android support library" extras.
- Root access on your Android device, with ability to run "su".
- Android debug bridge - adb (from the Android SDK).
- Ant (or Eclipse) for building Android apps.
- On Mac OS X, elf.h in /usr/include (http://www.swissdisk.com/~bcollins/macosx/elf.h)
You need to compile the Serval kernel module against the exact version of the kernel that runs on your Android device, or otherwise the kernel module will not load. The following web page gives an overview of how to get the kernel sources and perform a build.
http://source.android.com/source/building-kernels.html
For instance, to clone the kernel source for devices with an MSM CPU (e.g., Nexus One), do:
$ git clone https://android.googlesource.com/kernel/msm.git
For Galaxy Nexus phones you have to get the OMAP sources and for the Nexus 7 tablet the Tegra sources.
Having retrieved the source, you will be left with an empty checkout. To checkout a particular branch:
$ cd msm
$ git checkout remotes/origin/android-msm-2.6.35
The next step is to figure out the exact commit/version of the code used by the kernel running on your device. On the device, go to "Settings->About phone->Kernel version" to figure out the exact kernel version it is running. The version string should look something like "2.6.35.7-59465-g42bad32".
The first number identifies the version of the kernel, the second number is the repository-specific commit ID. The end of the string (following the 'g') denotes the prefix of the SHA1 hash that globally identifies the commit.
Now, use the hash string to checkout the exact commit that was used to compile the kernel for your device, e.g:
$ git checkout 42bad32
If there is no commit matching the kernel running on your device, you can try to use the "HEAD" commit of the repository and then manually specify the kernel string (see below).
Now you need to prepare your kernel source tree. First put the cross compiler in your path, e.g.:
$ export PATH=$PATH:/<path to NDK>/toolchains/arm-eabi-4.4.0/prebuilt/darwin-x86/bin
(NOTE that, if your NDK does not have the appropriate toolchain, you can also use a prebuilt toolchain from one of Google's repositories, as described in the 'building kernels' document linked to above. It seems that Android kernels are built with the arm-eabi toolchains, rather than the arm-linux-androideabi ones. If your kernel module does not load, complaining about unknown symbols, you might be using the wrong toolchain.)
Now, make sure you have the .config file for the kernel. If your device's kernel has support for /proc/config.gz
, you can pull the kernel configuration directly from your device:
$ adb pull /proc/config.gz
$ gunzip config.gz
$ cp config <path to kernel source>/.config
Otherwise, you need to get a kernel configuration by some other means (it might also work to generate one yourself). If you have a Galaxy Nexus phone, you can just do make defconfig tuna_defconfig
in the kernel source directory.
Configure the kernel sources:
$ ARCH=arm CROSS_COMPILE=arm-eabi- make oldconfig
Prepare the kernel source for compilation (you may also need to compile the kernel to generate the Module.symvers file):
$ ARCH=arm CROSS_COMPILE=arm-eabi- make prepare
Check that the generated kernel version string matches that of your device:
$ cat <path to kernel source>/include/config/kernel.release
If the string does not match, manually override the kernel version string so that it matches your device's, e.g.:
$ echo "-59465-g42bad32" > <path to kernel source>/.scmversion
After overriding, re-run the prepare step. Your kernel source tree is now ready.
NOTE: If your kernel module build fails, try compiling the kernel first. Also, on Macs, ensure you have a copy of elf.h
under /usr/include
(get from, e.g., here: http://www.swissdisk.com/~bcollins/macosx/elf.h).
Run (./autogen.sh) ./configure to generate the Makefiles.
Enter src/stack and issue the following command (you need the toolchain binaries in your PATH, as instructed above):
$ ARCH=arm CROSS_COMPILE=arm-eabi- make serval.ko KDIR=<Path to kernel source>
This step requires that you have the Android SDK installed along with the Android support library. This extra library is found under "Extras" in the Android SDK manager.
Compile the sources from the top-level directory (this will generate the Java bindings that the Serval app needs):
$ ./configure --with-android-sdk=<path/to/sdk>
$ make
Compile the kernel module as instructed above, if not already done.
Build the native libraries for Android (optionally, change the platform target in the jni/Application.mk
file beforehand):
$ cd android/Serval
$ <Path to NDK>/ndk-build
The libraries and binaries can now be found under "libs".
Build the Serval Android app with Ant:
$ cd android/Serval (If not already there)
$ ant debug
Install on a (rooted) Android device:
$ ant debug install
NOTE: The Ant build script will automatically copy the kernel module you built, from its location in src/stack/serval.ko
, into the assets folder in the Serval app directory (android/Serval/assets
). The module must be in the assets folder to be included in the Android package (APK). This automatic copying does not happen when building with Eclipse instead of Ant. Therefore, when building with Eclipse, manually copy the kernel module into the assets folder before building the APK.