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 下载驱动文件
首先查看源码分支列表,确定源码分支代号

Android4.4.4-r1分支代号KTU84P

Android6.0.1-r1分支代号MMB29K

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

KTU84P Nexus5驱动列表
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 (android-build@vpbs1.mtv.corp.google.com) (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 (android-build@kpfi6.cbf.corp.google.com) (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/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容