最近尝试编译了一下Android内核源码,不知道为什么编译出来的内核无法启动之前编译的Android 6.0.1_r17的镜像,搜索了很久,但仍是无解,所以重新选择了编译Android 7.1.1_r13这个源码分支,然后再根据启动的模拟器的内核版本,选择了相应的内核分支进行了编译,最终可以由编译出的内核成功启动模拟器,在此做一下记录。
下载内核源码
先在Android源码目录下创建一个kernel目录以存放Android内核源码,然后进入kernel目录
需要根据自己的设备来选择内核源码,可选择的克隆命令如下:
|
|
具体什么设备需要选择什么内核源码,请参考这里面的Downloading sources部分的说明。因为我需要编译的是模拟器的内核源码,所以需要选择goldfish工程。克隆完成后会在kernel目录下生成一个goldfish目录,内核源码就在该目录中,进入goldfish目录下,不过这会儿还看不到源码,需要checkout后才能看到源码,根据自己模拟器的内核版本选择相应的分支checkout。可以先通过以下命令查看仓库中的所有分支:
|
|
因为我的模拟器的内核版本是3.4.67,所以这里我选择checkout出android-goldfish-3.4这个分支,命令如下:
|
|
设置gcc预编译工具链
预编译工具链的命令在Android源码中的/prebuilts/gcc/###-x86/arm/arm-eabi-#.#/bin目录下,对于Android 7.1.1,其为/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin和/prebuilts/gcc/drawin-x86/arm/arm-eabi-4.8/bin,如果系统是苹果系统,需要使用后者,Linux使用前者。我用的是Mac,所以设置命令如下:
|
|
如果为Linux,则为:
|
|
编译内核
在进行编译之前,需要设置两个重要的环境变量,这两个环境变量的设置与设备有关,对于设备为模拟器的情况,其设置如下:
|
|
设置完成后,先需要生成.config文件,对于Android 4.0以上的系统,需使用如下命令:
|
|
对于Android4.0以下的系统,需使用如下命令:
|
|
该命令其实就是将/kernel/goldfish/arch/arm/configs/下的goldfish_armv7_defconfig文件内的Kconfig配置内容复制到/kernel/goldfish目录下的.config隐藏文件中,该文件保存着内核源码各个目录下Kconfig文件的配置。
然后便可根据自己的电脑的CPU情况选择-j#参数来启动编译:
|
|
编译过程中出现了
|
|
解决办法为:将这里头的内容另存为elf.h并拷贝到/kernel/goldfish/scripts/mod目录下,并将/kernel/goldfish/scripts/mod下的mk_elfconfig.c和modpost.h两个文件里的#include
编译成功后会看到如下输出:

运行新编译的内核
编译生成的内核镜像存放在/kernel/arch/arm/boot/目录下,镜像名为zImage,可通过-kernel参数执行emulator命令用自己编译出的内核启动模拟器,为了确保能够每次都可以正确的启动模拟器,需要在Android源码目录下执行以下命令:
|
|
lunch命令后跟的为编译Android源码时选择的目标,为模拟器编译Android源码时选择的目标应为aosp_arm-eng
然后通过以下命令打开模拟器
|
|
成功启动模拟器查看一下是否已经使用了我们自己编译的内核,结果如下:

可以看到内核已经变为我们自己编译出来的内核镜像了,到这里编译Android内核就圆满完成了!