领到一部Samsung Galaxy Nexus手机用来折腾,没有这个手机的工程文件包。直接从google的android网站找到4.2.1的映像文件覆盖之,然后root之。再去下载了kernel代码,根据折腾的需要编辑了.config。考虑到以后可能经常需要折腾这个内核的源代码,我得找到一个简单的方法来让这部手机接受我的折腾,我不改动除linux kernel外其他部分。下面是过程流水帐:

  • 下载内核
 git clone https://android.googlesource.com/kernel/omap.git
 cd omap
 git checkout remotes/origin/android-omap-tuna-3.0 -b tuna
  • 配置内核
 make tuna_defconfig
    • 编辑.config,确保如下配置项存在 (参见ARM DS-5相关的readme文件)
  CONFIG_GENERIC_TRACER=y
  CONFIG_TRACING=y
  CONFIG_PROFILING=y
  CONFIG_HIGH_RES_TIMERS=y
  CONFIG_LOCAL_TIMERS=y
  CONFIG_PERF_EVENTS=y
  CONFIG_HW_PERF_EVENTS=y
  CONFIG_DEBUG_MUTEXES=y
  CONFIG_DEBUG_INFO=y
  CONFIG_CPU_FREQ=y
 
  • 修改Makefile
    • 修改Makefile,使得
  SUBARCH :=arm
  ARCH ?= arm
  CROSS_COMPILE ?=arm-eabi-
  • 编译内核
 为了保持版本号的一致性(可能有些已经在手机中的内核模块依赖版本号,依赖版本号的例子见文章后的+)
 用adb shell cat /proc/version查看内核版本号,例如
   Linux version 3.0.31-gd5a18e0 ……
 在Makefile中定义  
   EXTRAVERSION =-gd5a18e0
 make kernelversion查看是否结果为3.0.31-gd5a18e0
 在.config中定义
 CONFIG_LOCALVERSION_AUTO=n
 强制定义本地版本号为空
 make LOCALVERSION=
 这样编译出来的内核版本号将和要被替换的内核一致
  • 定制boot.img
    • 我们需要取得目前手机的boot.img,采用如下方式(需要先root)
adb shell dd if=/dev/block/platform/omap/omap_hsmmc.0/by-name/boot of=/sdcard/boot.img
adb pull /sdcard/boot.img
    • 我们需要下载一个工具来解开boot.img,以便替换kernel
 mkdir mkimg
 cp boot.img mkimg
 cd mkimg
 git clone https://github.com/glandium/unbootimg.git
 git clone https://git.linaro.org/android/platform/system/core.git
 gcc -o unbootimg/unbootimg unbootimg/unbootimg.c core/libminicrypt/sha.c -Icore/include -Icore/mkbootimg
 unbootimg/unbootimg boot.img
    • 解开后有如下文件:
      • boot.img-mk: mkbootimg所需的一些选项和参数
      • boot.img-kernel: 内核映像,就是我们需要替换的
      • boot.img-ramdisk.cpio.gz: 就是ramdisk.img,我们这次不用管它,当然有需要也可以定制它
    • 然后,我们用如下命令生成新的boot.img (A)
 eval mkbootimg $(sed s,boot.img-kernel,<path-to-omap>/arch/arm/boot/zImage, boot-img.mk)
  • 烧制(B)
adb reboot-bootloader
fastboot devices如果能找到手机则可以立刻写boot.img
fastboot flash boot boot.img

fastboot reboot重启后,如果进入android桌面,就成功了。比如我这里重启后,

hzh@fangtian:~/git$ adb shell cat /proc/version
Linux version 3.0.31-gd5a18e0 (hzh@fangtian) (gcc version 4.6.x-google 20120106 (prerelease) (GCC) ) #2 SMP PREEMPT Mon Dec 10 16:42:24 CST 2012

以后要替换内核,编译好内核后,只需要重复(A)(B)两步即可。

+内核版本号变动后,内核模块不工作的一个例子:

root@android:/data/gator # Unable to load (insmod) gator.ko driver:
 >>> gator.ko must be built against the current kernel version & configuration
 >>> See dmesg for more details