主要参考了:"在Ubuntu上下载、编译和安装Android最新内核源代码(Linux Kernel)"一文
一.我首先按照android官网的指导,下载、并成功编译了android2.3.4源码
在我的机器上,android源码的存放位置为:~/android
二. 下载Linux Kernel for Android源代码
1. 使用GIT工具下载,执行以下命令:
$cd ~/android
$mkdir kernel
$cd kernel
$git clone http://android.git.kernel.org/kernel/common.git
我的机器是通过代理上的网,所以下载代码使用了http协议,要是能使用git协议,当然速度更快,更稳定点。我下载是android.git.kernel.org网站经常连不上,所以我ping了下android.git.all.kernel.org(注意中间多了个all),找到具体IP地址后,用实际的IP地址替换了上面的网址。android.git.all.kernel.org我试的时候,有3个网址,用git协议连的时候,一个连不上会连下一个,Http连的时候好像只能连其中一个。
下载完成后,在kernel目录下有一个common目录,Linux内核代码就在这里了。
注意:common.git代码是针对模拟器的Kernel代码,在android.git.kernel.org还有其他Kernel代码:experimental, msm (高通平台) , Omap (TI platform)
common.git/ 30-Aug-2011 00:37 -
experimental.git/ 24-Aug-2011 19:14 -
linux-2.6.git/ 30-Aug-2011 00:39 -
lk.git/ 24-Aug-2011 19:14 -
msm.git/ 24-Aug-2011 19:12 -
omap.git/ 30-Aug-2011 00:41 -
qemu.git/ 24-Aug-2011 19:14 -
samsung.git/ 24-Aug-2011 19:12 -
tegra.git/
2. 下载完成后,可以通过下列命令查看下载的内核代码版本:
$cd ~/android/kernel/common
$git branch
将显示版本号:Android-2.6.36
$git branch -a
* Android-2.6.36
remotes/origin/HEAD -> origin/Android-2.6.36
remotes/origin/Android-2.6.35
remotes/origin/Android-2.6.36
remotes/origin/archive/Android-2.6.25
remotes/origin/archive/Android-2.6.27
remotes/origin/archive/Android-2.6.29
remotes/origin/archive/Android-2.6.32
remotes/origin/archive/Android-gldfish-2.6.29
remotes/origin/archive/Android-goldfish-2.6.27
3,将分支切换到Android-gldfish-2.6.29
下载完成最新的kernel代码后,发现在arch/arm/configs下没有模拟器要使用的硬件配置文件goldfish_defconfig,而这个配置文件是编译内核代码时需要用到的,所以需要将分支切换到remotes/origin/archive/Android-gldfish-2.6.29。
$git checkout remotes/origin/archive/android-gldfish-2.6.29
切换完成后,就能在arch/arm/configs目录下看到goldfish_defconfig文件了。
三. 编译内核代码
1. 设置交叉编译工具目录路径到$PATH环境变量中去
$export PATH=$PATH:~/android/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin
注意:该工具是下载android源码下载下来的,当然可以在相关网站单独下载交叉编译工具。
2. 修改common目录下的Makefile文件的以下两行为:
修改
# ARCH ?= (SUBARCH)
# CROSS_COMPILE ?=
为
ARCH ?= arm#体系结构为arm
CROSS_COMPILE ?= arm-eabi-#交叉编译工具链前缀
注意:注释和前面的配置之间不要留空格,最好还是另起一行写,否则会引起编译错误。
arm-eabi-前不要加路径,否则引起编译错误。
3. 编译配置
$make ARCH=arm goldfish_defconfig
我这里必须加ARCH=arm ,否则报错
4,编译
$make
或
$make ARCH=arm CROSS_COMPILE=~/android/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-
不加CROSS_COMPILE,刚开始时也报一条错,但是否能编译成功,我没有试。
编译成功后,可看到下面两行:
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready
在执行make命令前,你也可以执行make menuconfig先配置一下编译选项(配置后编译是否会有问题,没有试过)。
四. 在模拟器中运行编译好的内核
1. 在启动模拟器之前,先设置模拟器的目录到环境变量$PATH中去:
$ export PATH=$PATH:~/android/out/host/linux-x86/bin
当然也可以用其他方法,因为我编译过SDK,所以我使用的是SDK中内容:export PATH=$PATH:/usr/bin/AndroidSDK/tools
2. 设置ANDROID_PRODUCT_OUT环境变量:
$export ANDROID_PRODUCT_OUT=~/android/out/target/product/generic
注:也可通过Android SDK工具创建AVD,我创建的AVD为test
如果不设置该环境变量,则可以在在源码目录下的out/target/product/generic/目录下运行
emulator -image system.img -data userdata.img -ramdisk ramdisk.img 命令
$cd ~/android/out/target/product/generic
$emulator -image system.img -data userdata.img -ramdisk ramdisk.img
3. 指定在后台启动模拟器,并使用新编的内核文件:
$emulator -kernel ~/android/kernel/common/arch/arm/boot/zImage &
或者(创建了AVD)
$emulator -kernel ~/android/kernel/common/arch/arm/boot/zImage @test &
注:我这里第一次启动很慢,不知是否是我的机器出问题了,我实在忍不了,用Kill将那个进程先杀死了,以后进就很快了。
4. 用adb工具连接模拟器,查看内核版本信息,看看模拟器上跑的内核是不是我们刚才编译出来的内核:
在这之前需要将adb工具所在的目录加入到PATH环境变量,可以通过find ~ -name adb查找。
$ adb shell
这时候如果是第一次运行 adb shell命令,会看到以下输出,不用管它,再运行一次adb shell命令就可以了。
* daemon not running. start it now on port 5037 *
* daemon started successfully *
error: device offline
切换到proc目录:
# cd proc
# cat version
Linux version 2.6.29-gb0d93fb-dirty (android@android23) (gcc version 4.4.3 (GCC) ) #1 Fri Jun 3 23:17:24 HKT 2011
从机器名android@android23和日期1 Fri Jun 3 23:17:24 HKT 2011可以看出,模拟器使用的内核即为刚刚编译出来的内核。
另外从一篇文章中看到,可以用下面的方法获取编译配置信息:
http://blog.csdn.net/hylaking/article/details/6622744
从prebuilt的模拟器中获取编译配置信息
$cd ~/android/kernel/common
$emulator @test &
$adb pull /proc/config.gz
$gunzip config.gz
$cp config .config
这样就不需要:二 3,将分支切换到Android-gldfish-2.6.29和三,2,3 步骤,这样编译出来的模拟器应该比较新,但我没有试过。
也可以从CodeSourcery上下载用于交叉编译的工具链:
http://www.codesourcery.com/gnu_toolchains/arm/download.html