Tuesday, October 11, 2011

Compiling kernel modules (tun.ko) for Android

If you want to use OpenVPN on your Android device, the first obstacle you have to face is trying to get the right network tunnel module for your phone's kernel. I always have a hard time to get the pre-compile version that matches the kernel I use. (Note: If you don't want to deal with this issue, you can always pick a kernel that comes with the tunnel module.) However, I always like to use the stock kernel which doesn't come with network tunnel module. So, after googling for awhile, I found out that compiling your own kernel module actually is not that difficult. First, I found this tutorial online http://sshrootat.blogspot.com/2011/06/compiling-tunko-for-android-openvpn.html by Sean Crosby. This is a very good tutorial; however, I encountered few issues when I tried to follow instruction. So, I want to share my steps here which are very close to Sean's tutorial but with extra details. Note: these steps are targeted for Tegra device like Motorola Xoom and assume you have basic Linux knowledge and a Linux machine around to compile the source.

  1. First thing you need is to find which kernel version you have on your device. 
    • "uname -a" will do the trick. Note: If you need a program like "Terminal Emulator" to run command on your Android device. The output of uname should look something like this "Linux localhost 2.6.36.3-g111d827...." The number "2.6.36.3" is the kernel version number you're looking for. And the "g111d827" is the build number which you will need later when you compile the module because the build number has to be identical between kernel and the module.
  2. Once you know the version you need, than you have to download the right source code. By the time I wrote this post, http://android.git.kernel.org was hacked and was offline for more than a month. So,  I found another alternative repository https://www.codeaurora.org/gitweb/quic/la/?p=kernel/tegra.git;a=heads. The web page listed all source branches in this repository. In this case, I would pick the branch "aosp/android-tegra-2.6.36". 
    • To clone the source, create a new directory "android-kernel" and than run this command "git clone git://codeaurora.org/kernel/tegra.git -b aosp/android-tegra-2.6.36". I will take awhile to download the source, you can let it run and continue to next step.
  3. Download the ARM crosscompiler from https://sourcery.mentor.com/sgpp/lite/arm/portal/release1293
    • create a directory "compiler" and extract the binary with this command "tar -jvxf arm-2010q1-202-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2" 
    • Since I'm not a Unix programmer and don't know much about cross compiler, if this compiler doesn't work with your Linux version (I'm using Ubuntu 10.4), than you may have to do some research finding the right one.
  4. Add the compiler bin to your path.
    • "export PATH=$PATH:~/android-kernel/compiler/arm-2010q1/bin"
  5. Once the source is downloaded, you should have "tegra" directory inside "android-kernel". Now, it's time to get your existing kernel configuration from your device. The file is located under "/proc" and called "config.gz". Download it to your linux machine and unzip it using "gunzip config.gz". Now, copy "config" file to "tegra" directory and rename it to ".config". You also need to make some changes to .config file.
    • update CONFIG_CROSS_COMPILE to match your cross compiler. In this case, "arm-none-linux-gnueabi-" is the value.
    • update CONFIG_LOCAL_VERSION to match your build number. In this case, it is "-g111d827".
    • if your .config file has CONFIG_LOCALVERSION_AUTO set to Y like mine, change it to #CONFIG_LOCALVERSION_AUTO is not set
    • last but the most important one is to make sure CONFIG_TUN is un-commented and set to m
  6. Modify the setlocationversion script so it won't display "+" symbol.
    • go to tegra directory
    • vi scripts/setlocalversion
    • locate the following line
      • if $short; then
      •      echo "+"
    • change echo "+" to echo ""
  7. Set the environment properties for the compiler
    • export ARCH=arm
  8. Compile the modules
    • go to "tegra" directory
    • run "make modules"
  9. If the compile succeed, you should find a tun.ko file under drivers/net.
    • run "strings tun.ko" to make the version is matching your kernel version.
  10. Now, copy the module file back to your Android device and enjoy OpenVPN.

18 comments:

  1. hey im stuck to this step
    this is mine git
    git clone git://codeaurora.org/kernel/msm.git -b aosp/android-msm-2.6.29

    wer do i create folder?? in my device or were
    how do i clone the kernel

    i used android terminal emulator.. but it showing
    "git: permission denied"

    mine kernel is linux locahost-2.6.29-perf
    "perf" is build number

    help me pls

    ReplyDelete
  2. I was using a Linux machine to cross compile the Android kernel so I downloaded the kernel source code to the linux machine and setup the correct cross compiler. In my case, since Xoom is using ARM processor so I downloaded and installed the ARM cross compiler. So, I wasn't using my device to compile.

    ReplyDelete
  3. im windows user, so dont know that much about linux, could you tel me can i use msysgit windows to clone the kernel..

    im in middle of this process, after completing i will ask another questions..
    too much trickie process
    thanks for the fastest reply..

    ReplyDelete
  4. Unfortunately, I don't have any experience in compiling the kernel on windows. The most important piece is the cross compiler. So, if you could find the right cross compiler for windows, I think it may be possible. However, I can't say it for sure because I have never tried it before. And, the process will be very different.
    I assumed you rooted your device already; otherwise, you can't install your own kernel module. If you have your device rooted but having trouble compiling your own kernel, may be you should consider to download a pre-build kernel that comes with the tunnel module so you don't have to build it. You could save you lot of time and trouble.


    .

    ReplyDelete
  5. Fucking Android is a fucking dog's shit. Where the fuck is now "make menuconfig"

    ReplyDelete
  6. By the way, for compiling the kernel you need a case-sensitive system..so Windows will not work.

    ReplyDelete
  7. Thanks for posting this. I needed to do exactly this for my new MyTouch Q, and your instructions led me right through the process with no issues (though for the benefit of those to follow me, let me note LG has made the MyTouch Q sources available at http://www.lg.com/global/support/opensource/opensource-detail.jsp
    which saves a couple of steps).

    ReplyDelete
  8. How do I compile tun.ko for 4.0.4 3.0.8+ kernel?

    ReplyDelete
  9. Hi Edgar, first you need to locate and download the source code for kernel 4.0.43.0.8. Try this official download page http://source.android.com/source/downloading.html. Once you have the correct source, I assume you can simply follow the instructions.

    ReplyDelete
    Replies
    1. hi there im noob here. can you do me a favor. can you compile a tun.ko for my android. im using 2.3.3 gingerbread
      2.6.35.7-perf p50174@bs217#1
      board and software version;MSM8260
      i need help please email me
      batosai20478123@gmail.com

      Delete
  10. This comment has been removed by the author.

    ReplyDelete
  11. Hey,
    Thank you very much for posting this guide, it is very helpful.
    I follow all your steps but at the end I don't have a tun.ko file. I do have a tun.c file however.
    I recieved two errors while running "make modules":
    make[1]:***[kernel/bounds.s] Error 127
    make: ***[prepare0] Error 2
    I'm trying to compile for a Galaxy Ace, version 2.3.35.7-perf-CL706042. sourcecode:http://code.google.com/p/the-ace-kernel/source/checkout

    ReplyDelete
  12. followed instructions but got several errors and no tun.ko.
    could use some help.
    thanks.

    ReplyDelete
  13. Thank you bro, great tutorial.
    If you got any errors try building with "make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- modules" in step 7
    It worked for me.

    ReplyDelete
  14. How to download the kernel:
    go to http://source.android.com/source/downloading.html
    follow all the instruction in your Linux pc, expcept the following command:
    repo init -u https://android.googlesource.com/platform/manifest -b android-4.0.1_r1
    change the android version with yours (you should have a list of the vaiable android from the command before this).
    Then launch:
    repo sync

    ReplyDelete
  15. Great tutorial ! so helpful.

    I just want to point out that if you're not able to run the command uname -a as I do, you can still find out which kernel version your android device is running by typing the following command.

    cat /proc/version

    cya

    Paulo Miguel Almeida

    ReplyDelete
  16. Can u hep me to compile for this kernel version 3.0.8-perf-g9d5151f my email is sanmidawodu@gmail.com

    ReplyDelete
  17. Hi, I compile kernel with make. What could be the reason that I don't get the module.ko binary to differ from previous module.ko after I changed source code in coresponding module.c and run make command again. I have deleted the kernel image before running make.

    ReplyDelete