Home > Android > Android Nexus S custom kernel

Android Nexus S custom kernel

As of my later post, you are not getting the Nexus S kernel source. And what is more it seems rather difficult to customize it (include new modules or facilities, etc.).

Next it is shown how to do so. It is not as difficult as expected and the procedure is quite similar to a kernel customization and build in a computer.

Thanks to Gbhil for his guide which is the base for this one [1].

Download source and fulfill requirements

First of all it is required you have downloaded the prebuilt ndk with the arm toolchain or the Android Source tree that also includes the prebuilt toolchain. I’m using the one from the source tree but there shouldn’t be any problem on using the other one.
Besides that, it is also possible to use the CodeSourcery for ARM toolchain GNU/Linux (the EABI one is for building without considering libc and some other GNU/Linux libraries) [2].

Download Nexus S kernel from the repository

$ cd ~/mydroid
$ git clone git://android.git.kernel.org/kernel/samsung.git
$ cd samsung

Configure and build the kernel

Configure your kernel

$ export ARCH=arm
$ export CROSS_COMPILE=<path_to_mydroid>/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-
$ export CCOMPILER=<path_to_mydroid>/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-
$ make ARCH=arm clean
$ make ARCH=arm herring_defconfig
$ make ARCH=arm oldconfig  <----- not necessary
$ make ARCH=arm menuconfig

In order to personalize kernel name, modify the Makefile (EXTRAVERSION):

VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 35
EXTRAVERSION = .7-jlanza
NAME = Yokohama

or do so on the make command line.

Compile the new kernel

$ make -j2 ARCH=arm 

or automatically retrieving the number of processors

$ make ARCH=arm CROSS_COMPILE=$CCOMPILER -j`grep 'processor' /proc/cpuinfo | wc -l`

or customizing the kernel name

$ make -j2 ARCH=arm CROSS-COMPILE=arm-eabi EXTRAVERSION=-yourkernel 

It takes less than 10 minutes in compile the whole kernel. It depends on the number of options you set.

In <kernel_source>arch/arm/boot/zImage you will find the zImage file.
The different modules are stored in each own directory:

$ find . -iname "*.ko"

Flashing the new kernel image

It is time to prepare the image to flash the new kernel. The kernel is embedded on the boot image so you will need to merge the new kernel image and ramdisk in order to create a boot image suitable for flashing. In [3] the procedure is explain in depth and there are several ways to do it. Here is the one tested and working.

Download the unpack-bootimg.pl and the repack-bootimg.pl. These scripts will help quite a bit.

$ chmod +x unpack-bootimg.pl repack-bootimg.pl

You need a working boot.img. The best you can do it get the one currently running on your phone.
The phone has several devices which hold the different parts of the filesystem.

$ ./adb shell
$ su
# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00200000 00040000 "bootloader"
mtd1: 00140000 00040000 "misc"
mtd2: 00800000 00040000 "boot"
mtd3: 00800000 00040000 "recovery"
mtd4: 1d580000 00040000 "cache"
mtd5: 00d80000 00040000 "radio"
mtd6: 006c0000 00040000 "efs"
# cat /dev/mtd/mtd2 > /sdcard/boot.img
# exit
$ ./adb pull /sdcard/boot.img 

or set the usb storage on and copy the file.

Note: when you made the ROM backup, such a file was also created. You can also use it.

Unpack the boot.img using unpack-bootimg.pl

$ ./unpack-bootimg.pl boot.img
$ ll
...
drwxr-xr-x  1 jlanza jlanza 8388608 2011-08-22 13:00 boot.img*
-rw-r--r--  1 jlanza jlanza 2828288 2011-08-22 13:01 boot.img-kernel.gz
drwxr-xr-x  8 jlanza jlanza    4096 2011-08-22 18:24 boot.img-ramdisk/
-rw-r--r--  1 jlanza jlanza 5558272 2011-08-22 13:01 boot.img-ramdisk.cpio.gz
...

That will place all of the files from the ramdisk in your working directory. You can now edit them.
It is recommended you edit at least default.prop, so you set it like: [4]

$ cat default.prop
#
# ADDITIONAL_DEFAULT_PROPERTIES
#
ro.secure=0                       # This allow adb shell to automatically log in as root
ro.allow.mock.location=0
ro.debuggable=0
persist.service.adb.enable=0

After changing the files, re-create the ramdisk

$ find . | cpio -o -H newc | gzip > ../ramdisk-repack.cpio.gz

Combine the kernel and your new ramdisk into the full image, using the mkbootimg program (which you should download and compile from the git repository).
If you have compiled the complete Android systems then you have all the tools in the directory out/host/linux-x86/bin/

$ mkbootimg --kernel your_zImage --ramdisk ramdisk-repack.cpio.gz --base 0x30000000 --pagesize 4096 -o newtestboot.img 

Note: --base 0x30000000 is required for the Nexus S

Another perl script may help you on the repacking, repack-bootimg.pl, but I prefer having more control over what it is done.

Flash the image

  • To test and see if it is working:
  • $ ./adb reboot bootloader
    $ ./fastboot boot newtestboot.img
    

    If the system reboots then everything has gone well, and you have your first kernel installed. You can play around with it. Notice that the wireless driver won’t be working unless you have installed it and other modules for the recompiled kernel.

  • To set the image change permanent
  • $ ./adb reboot bootloader
    $ ./fastboot flash boot newtestboot.img
    $ ./fastboot reboot
    

Compiling wifi kernel module

After installing a custom kernel, the wifi module may be unstable or unusable. The solution is to recompile the module, in case you haven’t dont it yet, linking it to the new kernel build.
Usually if you have compile the kernel, the wifi module is also compiled. For the Nexus S the module name is bcm4329.

Here I post an example of howto compile another wireless module. It is info directly from the web, sorry but I missed the reference 😦

cd ~/android/system/system/wlan/ti/sta_dk_4_0_4_32 
KERNEL_DIR=~/android/kernel/cm-kernel CROSS_COMPILE=$CCOMPILER ARCH=arm make -j`grep 'processor' /proc/cpuinfo | wc -l` 

A file named wlan.ko will be produced in the current directory. You must install the new module to the device.

$ adb shell mount -o remount,rw /system 
$ adb shell cp /system/modules/wlan.ko /system/modules/wlan.ko.backup 
$ adb push wlan.ko /system/modules/wlan.ko 

Reboot the device. If all goes well, you should be using the newly compiled ‘wlan.ko’.

For devices which may be utilizing wifi module from vendors other than TI, you may choose other appropriate drivers.

Install the modules for your customized kernel

It is recommended you have set the adb shell root access as other wise you have to do it a little bit more manual.

Option A: Using shell in phone

$ cd mykernel
$ for file in `find . -iname "*.ko"`; do cp "$file" /media/<nexus_s_sdcard>; done;
$ adb shell

Now on the new shell on the phone, make the /system rw

$ su
# mount
# mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system

Backup original wireless driver bcm4329.ko and copy the new modules

# cd /system/modules
# cp bcm4329.ko bcm4329.ko.orig
# cp /sdcard/* /system/modules/

Restore the former ro state to /system

# mount -o ro,remount -t yaffs2 /dev/block/mtdblock3 /system
# reboot

Option B: using adb (provided you have enabled root access on boot)

$ adb shell mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system 

or in case you have enabled ro.secure=0 in the default.prop file

$ adb remount 
remount succeeded

Copy modules to the appropiate directory

$ adb shell cp /system/modules/bcm4329.ko /system/modules/bcm4329.ko.orig
$ for file in `find . -iname "*.ko"`; do adb push "$file" /system/modules; done;
$ adb reboot

Option C: create a system.img

TODO

References

[1] [How-To] compile the Nexus S kernel from source – Android Forums
[2] Download Sourcery CodeBench Lite Edition for ARM
[3] HOWTO: Unpack, Edit, and Re-Pack Boot Images – Android Wiki
[4] rooting – Is there a way for me to run Adb shell as root without typing in `su`? – Android – Stack Exchange

Categories: Android Tags: , , , ,
  1. Lolyta
    March 29, 2012 at 03:02

    Thank’s devjlanza
    Nice post..
    [ask] From the step above, where is the different if i want to custom kernel for Samsung Galaxy Mini ?

    • jlanza
      March 29, 2012 at 12:50

      You should use the kernel of the SGMini. If you have the kernel source code of any mobile phone the procedure should be more or less the same.

  2. May 29, 2012 at 16:13

    Hi devjlanza,
    what should i do if i want to apply mobile IPv6 on android OS for PC
    thanks

    • jlanza
      May 29, 2012 at 16:37

      I really haven’t installed android on a PC. However I have another post on MIP on Ubuntu. The procedure to compile the kernel is very similar to the one for android, even easier as you don’t need to crosscompile.

  3. Ramiz Raja
    March 23, 2013 at 23:56

    Thanks for this great tutorial. I have built zImage using your guide but now i want to flash it in zip format using TWRP. How can i make flashable zip of zImage for Nexus S ?

    • jlanza
      March 25, 2013 at 14:55

      I didn’t work on that issue. I only flashed the ROM using the cable. I guess you will find lot of information out there. If you get one good link, please comment 😉

  1. September 12, 2011 at 17:32

Leave a comment