Android多版本源码及内核编译(Nexus5)

因研究逆向工程需要编译多个Android源码和内核在Nexus5真机上运行。通过记录编译过程,所以不会针对单个功能做详细介绍,初次接触的同学可以按照下面流程一步一步来进行环境搭建,资源准备,真机编译。


源码编译

目标

  • 编译Android4.4.4-r1源码及内核
  • 编译Android6.0.1-r1源码及内核

硬件环境

  • Ubuntu 14.0.4LTS
  • LG Nexus5 手机

环境JDK搭建

关于不同版本安卓源码对JDK版本的要求,如下是官方的文字描述:

....
C. AOSP 中 Android 的 master 分支:Ubuntu - OpenJDK 8;Mac OS - jdk 8u45 或更高版本
D. Android 5.x (Lollipop) - Android 6.0 (Marshmallow):Ubuntu - OpenJDK 7;Mac OS - jdk-7u71-macosx-x64.dmg
E. Android 2.3.x (Gingerbread) - Android 4.4.x (KitKat):Ubuntu - Java JDK 6;Mac OS - Java JDK 6
F. Android 1.5 (Cupcake) - Android 2.2.x (Froyo):Ubuntu - Java JDK 5
...

所以编译Android 4.4.4需要 Java JDK 6, 编译Android6.0.1需要openJDK7

Java JDK 6已经无法通过apt-get install方式安装, oracle官方下载地址

Java JDK 6安装过程:

1 把下载的文件放到自己定义的地方.
2 修改权限
$chmod 777 jdk-6u45-linux-x64.bin
3 执行
$./jdk-6u45-linux-x64.bin
4 配置环境变量
$sudo gedit /etc/profile

##添加到profile中保存
JAVA_HOME=$jdk1.6自定目录/jdk1.6.0_45 
JRE_HOME=$JAVA_HOME/jre
CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin:$JAVA_HOME/lib:$JAVA_HOME

5 使/etc/profile生效
$source /etc/profile
6 查看是否生效
$java –version

openJDK7 安装过程

终端上执行下面命令
$sudo apt-get install openjdk-7-jdk
正常情况下会安装到/usr/lib/jvm/java-7-openjdk-adm64/目录下

安装基础软件

$sudo apt-get install git-core gnupg flex bison gperf build-essential
    zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386
     lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache
     libgl1-mesa-dev libxml2-utils xsltproc unzip

安装Repo

1 创建目录

$ mkdir ~/bin
$ PATH=~/bin:$PATH

2 下载 Repo 工具

//使用了清华大学的镜像文件
$curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo
$chmod a+x ~/bin/repo

同步源码

1 建立工作目录

$mkdir WORKING_DIRECTORY
$cd WORKING_DIRECTORY

2 初始化仓库

//WORKING_DIRECTORY 源码要放的目录
$mkdir WORKING_DIRECTORY
$cd WORKING_DIRECTORY

初始化特定的 Android 版本列表文件,本文选择了两个支持Nexus 5的版本
,此处使用清华大学的镜像文件。

//android-4.4.4_r1使用
$repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-4.4.4_r1
//android-6.0.1_r1使用
$repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-6.0.1_r1

如果提示无法连接到 gerrit.googlesource.com,参考链接

3 同步源码
$repo sync –j4
同步时间看大家自己网络情况,我的网络比较好,大约花了2个小时同步一个版本

4 下载驱动文件
首先查看源码分支列表,确定源码分支代号

Android多版本源码及内核编译(Nexus5)_第1张图片
Android4.4.4-r1分支代号KTU84P

Android多版本源码及内核编译(Nexus5)_第2张图片
Android6.0.1-r1分支代号MMB29K

5 下载驱动
访问https://developers.google.com/android/nexus/drivers#hikey(暂时没发现国内有镜像,如果有需要的话加我QQ3231549366)中找到对应设备与源码分支的硬件驱动。

Android多版本源码及内核编译(Nexus5)_第3张图片
KTU84P Nexus5驱动列表
Android多版本源码及内核编译(Nexus5)_第4张图片
MMB29 Nexus5驱动列表

下载对应版本的渠道文件,依次解压三个文件,得到的三个shell脚本文件,将其置于源码根目录中再依次执行三个脚本,执行操作前,它会让你阅读相关协议,协议比较多有8项,最后输入I ACCEPT即可。执行完成以后会在源码的主目录生成一个vendor目录。注意执行shell的顺序,我第一次编译的时候没按照顺序执行,刷完机发现屏幕显示有问题,具体原因就没去研究,解决方法:删除了vendor目录,按照顺序又执行了一遍,重新编译后一切正常。

初始化编译环境

1 执行配置

//终端执行
$source build/envsetup.sh
//输出信息
including device/asus/deb/vendorsetup.sh
including device/asus/flo/vendorsetup.sh
including device/asus/fugu/vendorsetup.sh
including device/generic/mini-emulator-arm64/vendorsetup.sh
including device/generic/mini-emulator-armv7-a-neon/vendorsetup.sh
including device/generic/mini-emulator-mips/vendorsetup.sh
including device/generic/mini-emulator-x86_64/vendorsetup.sh
including device/generic/mini-emulator-x86/vendorsetup.sh
including device/htc/flounder/vendorsetup.sh
including device/huawei/angler/vendorsetup.sh
including device/lge/bullhead/vendorsetup.sh
including device/lge/hammerhead/vendorsetup.sh
including device/moto/shamu/vendorsetup.sh
including sdk/bash_completion/adb.bash

2 选择编译类型

//终端执行
$lunch
//输出信息
You're building on Linux

Lunch menu... pick a combo:
     1. aosp_arm-eng
     2. aosp_x86-eng
     3. aosp_mips-eng
     4. vbox_x86-eng
     5. aosp_hammerhead-userdebug
     6. aosp_mako-userdebug
     7. aosp_deb-userdebug
     8. aosp_tilapia-userdebug
     9. aosp_grouper-userdebug
     10. aosp_flo-userdebug
     11. mini_armv7a_neon-userdebug
     12. mini_mips-userdebug
     13. mini_x86-userdebug
     14. aosp_manta-userdebug

Which would you like? [aosp_arm-eng]
//选择5, 因为Nexus5设备代号就是hammerhead,会出现下面的输出信息

#### make completed successfully  ####
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=4.4.4
TARGET_PRODUCT=aosp_hammerhead
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
TARGET_CPU_VARIANT=krait
HOST_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-4.2.0-27-generic-x86_64-with-Ubuntu-14.04-trusty
HOST_BUILD_TYPE=release
BUILD_ID=KTU84P
OUT_DIR=out
============================================

3 检查Java环境

//终端执行
$java –version 

//Android 4.4.4 需要 Java JDK 6
//Android 6.0.1需要open JDK7
    
//有的时候大家通过update-alternatives命令切换当前JAVA环境。
//sudo update-alternatives --config java
//sudo update-alternatives --config javac
//sudo update-alternatives --config javaws
//envsetup.sh中会使用当前环境变量中JAVA_HOME指定的JDK,虽然Android 4.4.4有指定使用java6,最好还是通过修改/etc/profile中JAVA_HOME 指定jdk的版本,

编译

$make –j16
//j后面的参数取决于你电脑处理器的核心数,j=核心数*2 
大约2-3个小时。

刷机

1 进入recovery模式
将Nexus5设备连接到电脑上,打开usb调试,输入$sudo adb reboot bootloader 手机就会进入recovery模式。
2 刷机

$fastboot flashall –w
//或者fastboot -w flashall 刷机的过程大概在一至两分钟左右,刷机结束后会自动开机。

内核编译

下载内核

当前工程目录下新建kernel目录,同步远程kernel代码仓库到本地

$git clone https://aosp.tuna.tsinghua.edu.cn/kernel/msm.git
//仓库文件大概有1.2G的大小,同步完成以后本地有文件夹msm

确认分支

$cd msm
$git branch -a
//终端会输出如下信息
    .
    .
    .
  remotes/origin/android-msm-hammerhead-3.4-kitkat-mr1
  remotes/origin/android-msm-hammerhead-3.4-kitkat-mr2
  remotes/origin/android-msm-hammerhead-3.4-kk-fr1
  remotes/origin/android-msm-hammerhead-3.4-kk-fr2
  remotes/origin/android-msm-hammerhead-3.4-kk-r1
  remotes/origin/android-msm-hammerhead-3.4-l-preview
  remotes/origin/android-msm-hammerhead-3.4-lollipop-mr1
  remotes/origin/android-msm-hammerhead-3.4-lollipop-mr1.1
  remotes/origin/android-msm-hammerhead-3.4-lollipop-release
  remotes/origin/android-msm-hammerhead-3.4-m-preview
  remotes/origin/android-msm-hammerhead-3.4-marshmallow
  remotes/origin/android-msm-hammerhead-3.4-marshmallow-mr1
  remotes/origin/android-msm-hammerhead-3.4-marshmallow-mr2
  remotes/origin/android-msm-hammerhead-3.4-marshmallow-mr3
    .
    .
    .

1 Android4.4.4_r1分支

remotes/origin/android-msm-hammerhead-3.4-kitkat-mr2

2 Android6.0.1_r1分支
按照设备代号,源码中的内核版本号,Android版本代号描述,有3个分支

remotes/origin/android-msm-hammerhead-3.4-marshmallow-mr1
remotes/origin/android-msm-hammerhead-3.4-marshmallow-mr2
remotes/origin/android-msm-hammerhead-3.4-marshmallow-mr3

理论上面这3个分支都可以使用,mr是"maintenance release"简写。因工作需要本文还是需要和源码中的kernel一致
3 通过官方提供的命令行获取
非 Nexus 5 (hammerhead)运行以下命令

$ dd if=kernel bs=1 skip=$(LC_ALL=C grep -a -b -o $'\x1f\x8b\x08\x00\x00\x00\x00\x00' kernel | cut -d ':' -f 1) | zgrep -a 'Linux version'
//Kernel在源码out/target/product/hammerhead/目录下

对于 Nexus 5 (hammerhead),请运行以下命令:

$ dd if=zImage-dtb bs=1 skip=$(LC_ALL=C od -Ad -x -w2 zImage-dtb | grep 8b1f | cut -d ' ' -f1 | head -1) | zgrep -a 'Linux version'
//zImage-dtb在源码/device/lge/hammerhead-kernel目录下

//Android4.4.4-r1输出信息
Linux version 3.4.0-gd59db4e ([email protected]) (gcc version 4.7 (GCC) ) #1 SMP PREEMPT Mon Mar 17 15:16:36 PDT 2014
    Linux version CIFS VFS Client for Linux<7>%s: sess setup type %

//Android6.0.1-r1输出信息
Linux version 3.4.0-g7717f76 ([email protected]) (gcc version 4.8 (GCC) ) #1 SMP PREEMPT Wed Nov 4 21:42:24 UTC 2015
    Linux version CIFS VFS Client for Linux<7>%s: sess setup type %d

Linux version 3.4.0-gd59db4e 文本中d59db4e是git commit版本号信息
Linux version 3.4.0-g7717f76 文本中7717f76是git commit版本号信息

4 在关于手机内核版本信息查看
5 在代码中或者adb中通过cat /proc/version信息查看

内核源码下载

//输入终端命令获取到对应的内核源码:
//Android4.4.4-r
$ git checkout d59db4e
或者
$ git checkout -b remotes/origin/android-msm-hammerhead-3.4-kitkat-mr2

//Android6.0.1-r
$ git checkout 7717f76

内核源码编译

设置环境变量

//需要设置环境变量可以在kernel源码根目录下build.config文件中查看
//Android6.0.1-r1
$export ANDROID_SRC_PATH=源码根目录
$export PATH=$ANDROID_SRC_PATH/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin:$PATH 
$export ARCH=arm
$export SUBARCH=arm
$export CROSS_COMPILE=arm-eabi-

//Android4.4.4-r1
$export ANDROID_SRC_PATH=源码根目录
$export PATH=$ANDROID_SRC_PATH/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin:$PATH 
$export ARCH=arm
$export SUBARCH=arm
$export CROSS_COMPILE=arm-eabi-

配置
$make hammerhead_defconfig

编译

$make

终端输出:Kernel: arch/arm/boot/zImage-dtb is ready 编译完成

使用zImage-dtb替换/device/lge/hammerhead-kernel/zImage-dtb文件重新编译源码,编译后boot.img的内核就是我们编译的内核,可以在手机的关于界面内核信息可以看到。

也可以通过如下文bootimg-tools针对当前编译后的boot.img重打包,毕竟重编译的时间太长了。

Boot.img重打包

bootimg-tools工具是一款基于mkbootimg开发的boot.img 解包重打包C语言工具,github地址:https://github.com/pbatard/bootimg-tools

1 下载编译bootimg-tools

//kernel/msm根目录终端命令行下执行
$mkdir bootimg-tools
$cd bootimg-tools
$git clone https://github.com/pbatard/bootimg-tools.git
$make 

编译完成以后,在 makebootimg目录下生成了相应的二进制执行文件,将该二进制文件所在路径添加到 PATH路径中。

2 终端上执行解包

$cd 源码目录/out/target/product/hammerhead/
$unmkbootimg –i boot.img

//执行完毕输出信息
/* 
kernel written to 'kernel' (8451496 bytes)
ramdisk written to 'ramdisk.cpio.gz' (923769 bytes)

To rebuild this boot image, you can use the command:
  mkbootimg --base 0 --pagesize 2048 --kernel_offset 0x00008000 --ramdisk_offset 0x02900000 --second_offset 0x00f00000 --tags_offset 0x02700000 --cmdline 'console=ttyHSL0,115200,n8 androidboot.hardware=hammerhead user_debug=31 maxcpus=2 msm_watchdog_v2.enable=1' --kernel kernel --ramdisk ramdisk.cpio.gz -o boot.img
*/

3 覆盖原来的kernel
把内核源码目录下生成的arch/arm/boot目录下的zImage-dtb拷贝到Android源码目录out/target/product/hammerhead下。
并改名为kernel(注意备份原始的kernel文件)

4 重打包
使用步骤2中输出的mkbootimg 命令

//ramdisk.cpio.gz boot.img 可以在命令上指定目录,例子是在当前目录下执行,所以不需要全路径
$cd 安卓源码目录/out/target/product/hammerhead/
$mkbootimg --base 0 --pagesize 2048 --kernel_offset 0x00008000 --ramdisk_offset 0x02900000 --second_offset 0x00f00000 --tags_offset 0x02700000 --cmdline 'console=ttyHSL0,115200,n8 androidboot.hardware=hammerhead user_debug=31 maxcpus=2 msm_watchdog_v2.enable=1' --kernel kernel --ramdisk ramdisk.cpio.gz -o boot.img

生成boot.img后,连接手机执行烧写

5 烧写

$ adb reboot bootloader
$ fastboot flash boot boot.img

总结

本文介绍了2个版本源码和内核编译,其它版本源码和内核版本类似,主要是如何确认细节部分文中也做了说明。
后续会写些逆向工程方面的学习资料,主要包含基础知识,相关工具介绍,逆向思维,主要是Android方面了。

参考文档:
1 https://source.android.com/source/requirements
2 http://blog.csdn.net/liu1075538266/article/details/51272398
3 https://mirrors.tuna.tsinghua.edu.cn/help/AOSP/

你可能感兴趣的:(Android多版本源码及内核编译(Nexus5))