第一次下载好Android源代码工程后,我们通常是在Android源代码工程目录下执行make命令,经过漫长的等待之后,就可以得到Android系统镜像system.img了。以后如果我们修改了Android源代码中的某个模块或者在Android源代码工程新增一个自己的模块,是不是还是执行make命令呢?答案是否定的,Google为我们准备了另外的命令来支持编译单独的模块,以及重新打包system.img的命令。在继续学习Android源代码之前,就让我们先来看看这个命令吧。

      一. 首先在Android源代码目录下的build目录下,有个脚本文件envsetup.sh,执行这个脚本文件后,就可以获得一些有用的工具:

      USER-NAME@MACHINE-NAME:~/Android$ .  ./build/envsetup.sh

      注意,这是一个source命令,执行之后,就会有一些额外的命令可以使用:

      - croot: Changes directory to the top of the tree.

      - m: Makes from the top of the tree.

      - mm: Builds all of the modules in the current directory.

      - mmm: Builds all of the modules in the supplied directories.

      - cgrep: Greps on all local C/C++ files.

      - jgrep: Greps on all local Java files.

      - resgrep: Greps on all local res/*.xml files.

      - godir: Go to the directory containing a file.

      这些命令的具体用法,可以在命令的后面加-help来查看,这里我们只关注mmm命令,也就是可以用它来编译指定目录的所有模块,通常这个目录只包含一个模块。

      二. 使用mmm命令来编译指定的模块,例如Email应用程序:

      USER-NAME@MACHINE-NAME:~/Android$ mmm packages/apps/Email/

      编译完成之后,就可以在out/target/product/generic/system/app目录下看到Email.apk文件了。Android系统自带的App都放在这具目录下。另外,Android系统的一些可执行文件,例如C编译的可执行文件,放在out/target/product/generic/system/bin目录下,动态链接库文件放在out/target/product/generic/system/lib目录下,out/target/product/generic/system/lib/hw目录存放的是硬件抽象层(HAL)接口文件,后面的文章里面,我们会陆续提及到,敬请关注。

      三. 编译好模块后,还要重新打包一下system.img文件,这样我们把system.img运行在模拟器上时,就可以看到我们的程序了。

      USER-NAME@MACHINE-NAME:~/Android$ make snod


make snod生成的system.img为sparse格式,system.img有raw ext4 image和sparse ext4 image格式。

raw ext4 image,即经常说的raw image,使用file观察它: 其特点是完整的ext4分区镜像(包含很多全零的无效填充区),可以直接使用mount进行挂载,因此比较大。

另一种是sparse ext4 image,即经常说的simg,使用file观察它:





1

2




​$ file system.img​​​​system.img: data​



就是说是一个非常普通的dat文件。由于它将raw ext4进行稀疏描述,因此尺寸比较小(没有全零的无效填充区,一般在300到500M之间)。

android本身提供了源代码工具在两者之间转换,源代码位于:





1

2




​system/core/libsparse/simg2img.c ​​​​// 将sparse image转换为raw image;​​​​system/core/libsparse/img2simg.c ​​​​// 将raw image转换为sparse image;​




如果完整的进行过一次Android的编译,默认会将simg2img当作主机工具编译出来,放在out/host/linux-x86/bin/simg2img处。 但默认是不会编译img2simg的,我们可以手工进行编译:​​



1

2

3




​$ . build/envsetup.sh​​​​$ lunch aosp_hammerhead-userdebug​​​​$ make img2simg_host​




这样就会编译出out/host/linux-x86/bin/img2simg。 如果要将system.raw.img转换为system.simg: $ img2simg system.raw.img system.simg

为了方便没有源代码的同学,这里提供img2simg的​下载​路径

对于simg2img,到处都可以找到了,还有​windows​版本的,这里就不提供了。 


参考:

1 《​​如何单独编译Android源代码中的模块​​》--老罗


2 《Android中system.img的两种格式及其相互转换方法》

在此表示感谢。