天天看点

Android系统源代码编译—[5]构建内核选择一个内核下载源代码搭建编译环境配置内核编译内核运行内核

本文描述了仅构建内核的细节。接下来的说明假设你已经下载了完整的AOSP,并分别以真机和模拟器为例描述构建过程。

如果你是按照前面的文章已经下载了完整的Android代码就说明你的AOSP是完整的。

选择一个内核

这个表列出来内核源代码和二进制文件的名称和位置:

Device Binary location Source location Build configuration
hikey device/linaro/hikey-kernel kernel/hikey-linaro hikey_defconfig
angler device/huawei/angler-kernel kernel/msm angler_defconfig
bullhead device/lge/bullhead-kernel kernel/msm bullhead_defconfig
shamu device/moto/shamu-kernel kernel/msm shamu_defconfig
fugu device/asus/fugu-kernel kernel/x86_64 fugu_defconfig
volantis device/htc/flounder-kernel kernel/tegra flounder_defconfig
hammerhead device/lge/hammerhead-kernel kernel/msm hammerhead_defconfig
flo device/asus/flo-kernel/kernel kernel/msm flo_defconfig
deb device/asus/flo-kernel/kernel kernel/msm flo_defconfig
manta device/samsung/manta/kernel kernel/exynos manta_defconfig
mako device/lge/mako-kernel/kernel kernel/msm mako_defconfig
grouper device/asus/grouper/kernel kernel/tegra tegra3_android_defconfig
tilapia device/asus/grouper/kernel kernel/tegra tegra3_android_defconfig
maguro device/samsung/tuna/kernel kernel/omap tuna_defconfig
toro device/samsung/tuna/kernel kernel/omap tuna_defconfig
panda device/ti/panda/kernel kernel/omap panda_defconfig
stingray device/moto/wingray/kernel kernel/tegra stingray_defconfig
wingray device/moto/wingray/kernel kernel/tegra stingray_defconfig
crespo device/samsung/crespo/kernel kernel/samsung herring_defconfig
crespo4g device/samsung/crespo/kernel kernel/samsung herring_defconfig

真机(Nexus 5)

可以通过使用/dev/block/platform目录下的条目,来确定目标设备使用的芯片,

root@hammerhead:/dev/block/platform # ls
msm_sdcc.
           

我这里是Nexus 5 得到的芯片信息是msm。

模拟器

模拟器的内核固定是goldfish。

下载源代码

Nexus 5

选择好要构建的内核后,就可以通过git clone开始下载对应的内核源代码,

[email protected]:~/android_source/android_442# mkdir kernel && cd $_
[email protected]:~/android_source/android_442/kernel# git clone \
> https://android.googlesource.com/kernel/msm.git
           

Clone完成后,我们就得到了对应代码分支的仓库,然而你会发现当前目录下没有任何文件,

root@Tangxx:~/android_source/android_442/kernel# cd msm
root@Tangxx:~/android_source/android_442/kernel/msm# ls
root@Tangxx:~/android_source/android_442/kernel/msm#
           

要获得AOSP支持设备的内核源代码,最后一步是check out正确的commit,由于在git仓库中kernel文件的commit信息和文档,总是落后于新设备的发布,我们可以使用/proc/version下的版本字符串,或者解压后的内核镜像。这里使用/proc/version下的版本字符串:

[email protected]:/ # cat /proc/version                                          
Linux version -gadb2201 ([email protected].mtv.corp.google.com) (gcc version  (GCC) ) #1 SMP PREEMPT Wed Nov 20 14:42:53 PST 2013
           

在获得的版本信息中最重要的是内核版本号中3.4.0-g后面的7位十六进制数字—adb2201 。用这个字符串就能check out 出准确的commit,

root@Tangxx:~/android_source/android_442/kernel/msm# git checkout adb2201
HEAD is now at adb2201… mm: Hold a file reference in madvise_remove
           

至此,已经获得了目标设备的内核源代码副本。

模拟器

模拟器git clone goldfish版本内核,

[email protected]:~/android_source/android_442/kernel# git clone \
> http://android.googlesource.com/kernel/goldfish.git
           

git clone完成后,可以使用

来查看支持那些Linux内核版本的下载,这里直接选择3.4版本内核进行下载,

Android系统源代码编译—[5]构建内核选择一个内核下载源代码搭建编译环境配置内核编译内核运行内核
root@Tangxx:~/android_source/android_442/kernel/goldfish# git checkout -t \
> remotes/origin/android-goldfish- -b goldfish3.
           

搭建编译环境

编译内核需要正确的编译环境,包括ARM编译工具链以及各种编译工具(eg,make),本文主要使用AOSP中预编译好的工具链。

第一步,配置编译环境,

Android系统源代码编译—[5]构建内核选择一个内核下载源代码搭建编译环境配置内核编译内核运行内核

Nexus 5 hammerhead

Android系统源代码编译—[5]构建内核选择一个内核下载源代码搭建编译环境配置内核编译内核运行内核
Android系统源代码编译—[5]构建内核选择一个内核下载源代码搭建编译环境配置内核编译内核运行内核

模拟器

Android系统源代码编译—[5]构建内核选择一个内核下载源代码搭建编译环境配置内核编译内核运行内核

这样AOSP目录就有了编译工具链,可以通过查询编译版本确认,

Android系统源代码编译—[5]构建内核选择一个内核下载源代码搭建编译环境配置内核编译内核运行内核

第二步,设定系统环境变量通知内核我们使用的编译工具链,

root@Tangxx:~/android_source/android_442# cd kernel/msm/
root@Tangxx:~/android_source/android_442/kernel/msm# export CROSS_COMPILE=arm-eabi-
root@Tangxx:~/android_source/android_442/kernel/msm# export SUBARCH=arm
root@Tangxx:~/android_source/android_442/kernel/msm# export ARCH=arm
root@Tangxx:~/android_source/android_442/kernel/msm#
           

如果内核代码不在AOSP目录里,则需要将编译工具链添加到当前环境变量中,上面由于我的内核代码就在源代码目录中,所以没有添加,

export PATH=<AndroidSourceDir>/prebuilts/gcc/linux-x86/arm/arm-eabi-
/bin/:$PATH
           

Nexus 5X bullhead

设定系统环境变量,

tangxx@tangxx ~/android_source/android_70/kernel/msm $ export ARCH=arm64
tangxx@tangxx ~/android_source/android_70/kernel/msm $ export CROSS_COMPILE=aarch64-linux-android-
           

同样,如果内核代码不在AOSP目录,需要额外的设置,

至此,编译环境就搭建好了。

配置内核

Linux内核支持很多架构和硬件组合,为了能够给任意一种配置组合编译内核,可以指定一个defconfig的配置面板,这个模板位于/arch/arm/configs目录中,比如,Nexus 5 的hammerhead代码版本可以使用hammerhead_defconfig。

最终编译系统会读取该配置模板,并写入.config文件中。

.config文件隐藏在内核代码根目录/kernel/msm下,可以通过CTRL+H查看,除了使用模板,还可以直接编辑这个配置文件,但推荐使用模板。
           

这里直接使用默认的配置面板即可,如果需要对编译后的内核进行调试,就需要修改特定的配置了,后续文章会讲到。

编译内核

当完成编译环境配置和内核配置后,就可以执行编译了,

root@Tangxx:~/android_source/android_442/kernel/msm# make
[…]
 Kernel:arch/arm/boot/zImage is ready
root@Tangxx:~/android_source/android_442/kernel/msm#
           

至此,内核就编译完成了。

运行内核

编译完成后,可以通过下面命令来生成内核boot.ing文件,

tangxx android_601 # export TARGET_PREBUILT_KERNEL=<msm_dir>/arch/arm64/boot/Image.gz-dtb
tangxx android_601 # source build/envsetup.sh
tangxx android_601 # lunch 
tangxx android_601 # make bootimage
           

其中msm_dir为内核所在的目录。

生成的boot.ing文件就在android编译结果根目录下,我的在out/target/product/bullhead/boot.img。

tangxx android_601 # cd out/target/product/bullhead
tangxx bullhead # adb reboot-bootloader
tangxx bullhead # fastboot flash boot boot.img
target reported max download size of  bytes
sending 'boot' ( KB)...
OKAY [  368s]
writing 'boot'...
OKAY [  199s]
finished. total time: 567s
tangxx bullhead # fastboot reboot
           

完事。