转身搁浅昨天

不忘初心,方得始终

Endevour To Be A Humanistic Programmer


编译Android内核

最近尝试编译了一下Android内核源码,不知道为什么编译出来的内核无法启动之前编译的Android 6.0.1_r17的镜像,搜索了很久,但仍是无解,所以重新选择了编译Android 7.1.1_r13这个源码分支,然后再根据启动的模拟器的内核版本,选择了相应的内核分支进行了编译,最终可以由编译出的内核成功启动模拟器,在此做一下记录。

下载内核源码

先在Android源码目录下创建一个kernel目录以存放Android内核源码,然后进入kernel目录

需要根据自己的设备来选择内核源码,可选择的克隆命令如下:

1
2
3
4
5
6
7
8
9
$ git clone https://android.googlesource.com/kernel/common.git
$ git clone https://android.googlesource.com/kernel/hikey-linaro
$ git clone https://android.googlesource.com/kernel/x86_64.git
$ git clone https://android.googlesource.com/kernel/exynos.git
$ git clone https://android.googlesource.com/kernel/goldfish.git
$ git clone https://android.googlesource.com/kernel/msm.git
$ git clone https://android.googlesource.com/kernel/omap.git
$ git clone https://android.googlesource.com/kernel/samsung.git
$ git clone https://android.googlesource.com/kernel/tegra.git

具体什么设备需要选择什么内核源码,请参考这里面的Downloading sources部分的说明。因为我需要编译的是模拟器的内核源码,所以需要选择goldfish工程。克隆完成后会在kernel目录下生成一个goldfish目录,内核源码就在该目录中,进入goldfish目录下,不过这会儿还看不到源码,需要checkout后才能看到源码,根据自己模拟器的内核版本选择相应的分支checkout。可以先通过以下命令查看仓库中的所有分支:

1
git branch -a

因为我的模拟器的内核版本是3.4.67,所以这里我选择checkout出android-goldfish-3.4这个分支,命令如下:

1
git checkout remotes/origin/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,所以设置命令如下:

1
export PATH=$(Android源码目录)/prebuilts/gcc/darwin-x86/arm/arm-eabi-4.8/bin:$PATH

如果为Linux,则为:

1
export PATH=$(Android源码目录)/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin:$PATH

编译内核

在进行编译之前,需要设置两个重要的环境变量,这两个环境变量的设置与设备有关,对于设备为模拟器的情况,其设置如下:

1
2
export ARCH=arm
export CROSS_COMPILE=arm-eabi-

设置完成后,先需要生成.config文件,对于Android 4.0以上的系统,需使用如下命令:

1
make goldfish_armv7_defconfig

对于Android4.0以下的系统,需使用如下命令:

1
make goldfish_defconfig

该命令其实就是将/kernel/goldfish/arch/arm/configs/下的goldfish_armv7_defconfig文件内的Kconfig配置内容复制到/kernel/goldfish目录下的.config隐藏文件中,该文件保存着内核源码各个目录下Kconfig文件的配置。

然后便可根据自己的电脑的CPU情况选择-j#参数来启动编译:

1
make -j4

编译过程中出现了

1
'elf.h' file not found的问题

解决办法为:将这里头的内容另存为elf.h并拷贝到/kernel/goldfish/scripts/mod目录下,并将/kernel/goldfish/scripts/mod下的mk_elfconfig.c和modpost.h两个文件里的#include改为#include “elf.h”

编译成功后会看到如下输出:

make_success_display

运行新编译的内核

编译生成的内核镜像存放在/kernel/arch/arm/boot/目录下,镜像名为zImage,可通过-kernel参数执行emulator命令用自己编译出的内核启动模拟器,为了确保能够每次都可以正确的启动模拟器,需要在Android源码目录下执行以下命令:

1
2
source build/envsetup.sh
lunch aosp_arm-eng

lunch命令后跟的为编译Android源码时选择的目标,为模拟器编译Android源码时选择的目标应为aosp_arm-eng

然后通过以下命令打开模拟器

1
emulator -kernel kernel/arch/arm/boot/zImage

成功启动模拟器查看一下是否已经使用了我们自己编译的内核,结果如下:

emulator_display

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

最近的文章

解决Mac下make menuconfig出现的错误

在编译自己编写的Linux内核驱动模块之前,通常需要通过make menuconfig命令来配置内核驱动模块的编译方式,在Mac下调用该命令时可能会出现一些错误,这里记录一下相关错误与解决办法。 借着这个机会,顺便先介绍一下Linux内核的配置机制。 Linux内核配置系统组成Linux内核配置系统 …

于  AOSP 继续阅读
更早的文章

macOS Sierra 编译Android源代码

​这两天捣鼓了一下Android 6.0.1源码的下载与编译,碰到了不少坑,但最后还是成功地编译出了一份源码,在这里记录一下自己的操作过程,第一次写博客,还希望大家体谅我的渣渣水平。 搭建环境先交代一下自己的硬件情况: 操作系统:macOS Sierra CPU:双核四线程(后头有用) ​ …

于  AOSP 继续阅读
comments powered by Disqus