MTK6577+Android编译之android

MTK6577采用的内存芯片为H9TP32A4GDMCPR,包括4GB的eNAND和512MB的 LPDDR2,先升级为H9TP32A8JDMCPR,包括4GB的eNAND和1GB的LPDDR2

 

先来看MTK源代码树概观图:

MTK6577+Android编译之android_第1张图片

图1

由图1可知编译的入口是makeMtk文件,其采用perl语言编写的,包装了编译命令,下面来看编译系统的概述:

MTK6577+Android编译之android_第2张图片

图2

 

1.     编译命令、时间和生成的文件

 

(1)  编译命令和时间

编译命令./mk r dr,时间约为54分钟。

 

(2)  编译生成的文件

编译后发现有更新的文件有bootimg、kernel、ramdisk.img、ramdisk-recovery.img、recovery.img、secro.img和system.img

 

编译后有更新的log文件有hsimobile77_ics2_check-dep、hsimobile77_ics2_custgen、hsimobile77_ics2_check-modem、hsimobile77_ics2_sign-modem、hsimobile77_ics2_AppAssets_Overlay、hsimobile77_ics2_android

 

其中hsimobile77_ics2_check-dep、hsimobile77_ics2_custgen、hsimobile77_ics2_ptgen和编译preloader部分内容是一样的,可参考:

http://blog.csdn.net/loongembedded/article/details/38706537

 

(3)  android镜像的文件名system.img

 

我们来看\mediatek\build\makemtk.mk下面的相关内容:

[plain]  view plain copy
  1. LOGDIR        = $(MKTOPDIR)/out/target/product  
  2.    
  3. ANDROID_IMAGES   := $(LOGDIR)/$(PROJECT)/system.img \  
  4.                    $(LOGDIR)/$(PROJECT)/boot.img \  
  5.                    $(LOGDIR)/$(PROJECT)/recovery.img \  
  6.                    $(LOGDIR)/$(PROJECT)/secro.img \  
  7.                    $(LOGDIR)/$(PROJECT)/userdata.img  

其中boot.img和recovery.img是kernel相关的,system.img、secro.img、userdata.img和cache.img是有文件系统的,如果不烧录recovery.img,在启动过程中要进入recovery模式时黑屏。

 

 

2.     android编译流程

 

(1)  ./mk rdr

找到makeMtk源码(perl语言),编译命令最终是通过调用

$makeCmd ="make -f mediatek/build/makemtk.mk $cmdArg @mOpts";

这个编译命令进行编译的。GNU make可以添加DEBUG参数来获取调试信息,比如--debug=v。

可以通过修改$makeCmd来增加调试信息,比如:

$makeCmd ="make --debug=v -f mediatek/build/makemtk.mk $cmdArg @mOpts";

 

(2)  makemtk.mk

$makeCmd命令指定makefile文件 mediatek/build/makemtk.mk,其对应

[plain]  view plain copy
  1. android:  
  2. ifeq ($(ACTION), )  
  3.        $(hide) /usr/bin/perlmediatek/build/tools/mtkBegin.pl $(FULL_PROJECT)  
  4. endif  
  5.    
  6. ifneq($(DR_MODULE),)  
  7.    ifneq ($(ACTION), clean)  
  8.        $(hide) echo building android moduleMODULE=$(DR_MODULE)  
  9.        $(hide) perlmediatek/build/tools/javaoptgen.pl $(PRJ_MF) $(OPTR_MF)  
  10.        $(MAKECMD) $(DR_MODULE)  
  11.    else  
  12.        $(hide) echo cleaning android moduleMODULE=$(DR_MODULE)  
  13.        $(hide) $(MAKECMD) clean-$(DR_MODULE)  
  14.    endif  
  15. else  
  16.        $(hide) echo $(SHOWTIME) $(SHOWBUILD)ing$@...  
  17.        $(hide) echo -e \\t\\t\\t\\b\\b\\b\\bLOG:$(S_MODULE_LOG)  
  18. ifeq($(SHOWBUILD), build)  
  19.        $(hide) perlmediatek/build/tools/javaoptgen.pl $(PRJ_MF) $(OPTR_MF) $(DEAL_STDOUT)  
  20. endif  
  21.        $(hide) $(MAKECMD) $(ACTION)$(DEAL_STDOUT) && \  
  22.         $(call chkImgSize,$(ACTION),$(PROJECT),$(SCATTER_FILE),$(if $(strip$(ACTION)),$(CHECK_IMAGE),$(ANDROID_IMAGES)),$(DEAL_STDOUT),&&) \  
  23.         $(SHOWRSLT) $${PIPESTATUS[0]} $(MODULE_LOG) $(ACTION) || \  
  24.         $(SHOWRSLT) $${PIPESTATUS[0]} $(MODULE_LOG) $(ACTION)  
  25.    
  26. ifeq ($(ACTION), )  
  27.        $(hide) /usr/bin/perlmediatek/build/tools/mtkFinalize.pl $(PROJECT) $(MTK_PLATFORM)$(MTK_EMMC_SUPPORT)  
  28. endif  
  29. endif  

(3)  执行chkImgSize(if MTK_CHKIMGSIE_SUPPORT=yes)

主要是为了检查scatter file文件(MT6577_Android_scatter_emmc.txt)为uboot分配的空间是否可以容纳生成的image,目前看了mediatek\config\prj\ProjectConfig.mk文件中没有MTK_CHKIMGSIE_SUPPORT定义,后面应该考虑添加进来。

 

 

3.     android编译涉及的源代码目录

修改以下文件或者目录需要./mk r(n) dr

这部分参考第4部分。

 

4.     Boot.img、ramdisk.img、kernel、secro.img、ramdisk-revovery.img、system.img、cache.img和userdata.img

 

4.1  ./mk bootimag

编译生成boot.img、ramdisk.img和kernel,当修改kernel和root相关的代码时采用此命令:

alps/kernel/

alps/mediatek/platform/mt65xx/kernel/

alps/mediatek/source/kernel/

alps/mediatek/customer/mt65xx/kernel/

alps/mediatek/customer/common/kernel/

alps/mediatek/customer/$porject_name$/kernel

......

 

Android 产品中,内核格式是Linux标准的zImage,根文件系统采用ramdisk格式。这两者在Android下是直接合并在一起取名为boot.img,会放在一个独立分区当中。这个分区格式是Android自行制定的格式。Android开发时,最标准的做法是重新编译于内核和根文件系统,然后调用Android给的命令行文件mkbootimg来打包。

 

1)     mkbootimage打包生成boot.img


图3

\build\core\Makefile文件相关的一部分内容如下:

[plain]  view plain copy
  1. INSTALLED_BOOTIMAGE_TARGET:= $(PRODUCT_OUT)/boot.img  
  2. BUILT_RAMDISK_TARGET:= $(PRODUCT_OUT)/ramdisk.img  
  3.    
  4. INSTALLED_RAMDISK_TARGET:= $(BUILT_RAMDISK_TARGET)  
  5.    
  6. ifeq """$(CUSTOM_BUILD_VERNO)"  
  7.   CUSTOM_BUILD_VERNO := $(BUILD_NUMBER)  
  8.   CUSTOM_BUILD_VERNO := $(substeng.$(USER).,,$(CUSTOM_BUILD_VERNO))  
  9. endif  
  10.    
  11. #-----------------------------------------------------------------  
  12. # the boot image,which is a collection of other images.  
  13. INTERNAL_BOOTIMAGE_ARGS:= \  
  14.        $(addprefix --second,$(INSTALLED_2NDBOOTLOADER_TARGET)) \  
  15.        --kernel $(INSTALLED_KERNEL_TARGET) \  
  16.        --ramdisk $(INSTALLED_RAMDISK_TARGET)  
  17. ………………………  
  18. ifneq """$()"  
  19.   INTERNAL_BOOTIMAGE_ARGS += --board$(CUSTOM_BUILD_VERNO)  
  20. Endif  
  21. ………………………………………  
  22. $(INSTALLED_BOOTIMAGE_TARGET):$(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES)  

由此可见mkbootimage打包生成boot.img时需要的参数有

--kernel $(PRODUCT_OUT)/kernel(或是kernel_$project.bin)

--ramdisk $(PRODUCT_OUT)/ramdisk.img

--board $(CUSTOM_BUILD_VERNO)

注意CUSTOM_BUILD_VERNO不要超过16个字节,其在/mediate/config/prj/ProjectConfig.mk中定义,但这里其值为空,所以其内容对应于BUILD_NUMBER的值,这里的信息对应System settings->About phone->Custom buildversion下的内容,比如1407736091

 

mkbootimage工具位于out/host/linux-x86/bin,要知道boot.img的格式,需要看对应的源代码\system\core\mkbootimg\mkbootimg.c,boot.img由文件头信息boot header,压缩的内核,文件系统数据ramdisk以及second stage loader(可选)组成,它们之间非页面对齐部分用0填充,相关的代码见mian()下面部分:

[cpp]  view plain copy
  1. if(write(fd,&hdr, sizeof(hdr)) != sizeof(hdr)) goto fail;  
  2.     if(write_padding(fd, pagesize,sizeof(hdr))) goto fail;  
  3.    
  4.     if(write(fd, kernel_data, hdr.kernel_size)!= hdr.kernel_size) goto fail;  
  5.     if(write_padding(fd, pagesize,hdr.kernel_size)) goto fail;  
  6.    
  7.     if(write(fd, ramdisk_data,hdr.ramdisk_size) != hdr.ramdisk_size) goto fail;  
  8.     if(write_padding(fd, pagesize,hdr.ramdisk_size)) goto fail;  
  9.    
  10.     if(second_data) {  
  11.         if(write(fd, second_data,hdr.second_size) != hdr.second_size) goto fail;  
  12.         if(write_padding(fd, pagesize,hdr.ramdisk_size)) goto fail;  
  13. }  

\system\core\mkbootimg\bootimg.h目录下boot_img_hdr定义了文件头信息:

[cpp]  view plain copy
  1. typedef structboot_img_hdr boot_img_hdr;  
  2.    
  3. #define BOOT_MAGIC"ANDROID!"  
  4. #defineBOOT_MAGIC_SIZE 8  
  5. #defineBOOT_NAME_SIZE 16  
  6. #defineBOOT_ARGS_SIZE 512  
  7.    
  8. structboot_img_hdr  
  9. {  
  10.     unsigned char magic[BOOT_MAGIC_SIZE];  
  11.    
  12.     unsigned kernel_size;  /* size in bytes */  
  13.     unsigned kernel_addr;  /* physical load addr */  
  14.    
  15.     unsigned ramdisk_size; /* size in bytes */  
  16.     unsigned ramdisk_addr; /* physical loadaddr */  
  17.    
  18.     unsigned second_size;  /* size in bytes */  
  19.     unsigned second_addr;  /* physical load addr */  
  20.    
  21.     unsigned tags_addr;    /* physical addr for kernel tags */  
  22.     unsigned page_size;    /* flash page size we assume */  
  23.     unsigned unused[2];    /* future expansion: should be 0 */  
  24.    
  25.     unsigned char name[BOOT_NAME_SIZE]; /*asciiz product name */  
  26.      
  27.     unsigned char cmdline[BOOT_ARGS_SIZE];  
  28.    
  29.     unsigned id[8]; /* timestamp / checksum /sha1 / etc */  
  30. };  

Boot.img的组成借用bootimg.h下给出的解释:

MTK6577+Android编译之android_第3张图片

图4

 

2)     mkbootfs打包生成ramdisk.img


图5

 

在build/core/Makefile文件中看下面主要的相关部分:

[plain]  view plain copy
  1. ##################################################################  
  2. # Targets forboot/OS images  
  3. ##################################################################  
  4.    
  5. #-----------------------------------------------------------------  
  6. # the ramdisk  
  7. INTERNAL_RAMDISK_FILES:= $(filter $(TARGET_ROOT_OUT)/%, \  
  8.        $(ALL_PREBUILT) \  
  9.        $(ALL_COPIED_HEADERS) \  
  10.        $(ALL_GENERATED_SOURCES) \  
  11.        $(ALL_DEFAULT_INSTALLED_MODULES))  
  12.    
  13. BUILT_RAMDISK_TARGET:= $(PRODUCT_OUT)/ramdisk.img  
  14.    
  15. # We just buildthis directly to the install location.  
  16. INSTALLED_RAMDISK_TARGET:= $(BUILT_RAMDISK_TARGET)  
  17. $(INSTALLED_RAMDISK_TARGET):$(MKBOOTFS) $(INTERNAL_RAMDISK_FILES) | $(MINIGZIP)  
  18.        $(call pretty,"Target ram disk:$@")  
  19.        $(hide) $(MKBOOTFS) $(TARGET_ROOT_OUT) |$(MINIGZIP) > $@  
  20. ifneq ($(strip$(TARGET_NO_KERNEL)),true)         
  21.        $(hide) mediatek/build/tools/mkimage$(PRODUCT_OUT)/ramdisk.img ROOTFS > $(PRODUCT_OUT)/ramdisk_android.img  
  22.        mv $(PRODUCT_OUT)/ramdisk.imgmediatek/source/kernel/trace32/$(TARGET_PRODUCT)_ramdisk.img  
  23.        $(hide) mv$(PRODUCT_OUT)/ramdisk_android.img $(PRODUCT_OUT)/ramdisk.img  
  24. Endif  


MKBOOTFS =mkbootfs 就是位于out/host/linux-x86/bin目录下的mkbootfs。

Ramdisk.img是mkbootfs工具用\out\target\product\prj\out目录下的

 

需要注意system/core/rootdir中的部分内容是拷贝到了out/target/product/prj/system中的,并不是完完全全拷贝到out/target/product/prj/root目录中去的。

 

ramdisk映像是一个最基础的小型文件系统,它包括了初始化android系统所需要的全部核心文件,总之它控制着整个android的启动.例如:初始化init进程以及init.rc(可以用于设置很多系统的参数)等文件。以下是一个典型的ramdisk中包含的文件列表:

./init.trout.rc

./default.prop

./proc

./dev

./init.rc

./init

./sys

./init.goldfish.rc

./sbin

./sbin/adbd

./system

./data

详细可参考\system\core\rootdir\Android.mk。

 

3)     kernel

MTK6577+Android编译之android_第4张图片

图6

 

见http://blog.csdn.net/loongembedded/article/details/38778731

 

4.2  ./mk systemimage

 

1)     编译生成的文件

system.img、boot.img、ramdisk.img、ramdisk-recovery.img、recovery.img。

 

2)     修改system相关代码时用到此编译命令

alps/frameworks/

alps/packages/

alps/vendor/

alps/hardware/

alps/dalvik/

...........

3)     System.img文件的内容

 

在源码之后在 out/host/linux-x86/bin/下面会生成一个mkyaffs2image的工具,用这个可以把system目录打包成system.img

 

system.img文件是system目录的一个映像,类似于linux的根文件系统的映像,它包含了整个系统,比如android的framework、application、配置文件、字体等,它会被挂接到 "/" 上,包含了系统中所有的二进制文件。

 

android启动时首先加载ramdisk.img镜像,并挂载到/目录下,并进行了一系列的初始化动作,包括创建各种需要的目录,初始化console,开启服务等。System.img是在init.rc中指定一些脚本命令,通过init.c进行解析并挂载到根目录下的/system目录下的。

对于android系统文件夹,比如out/target/product/prj/system目录,说明如下:

 

system/app     

这个里面主要存放的是常规下载的应用程序,可以看到都是以APK格式结尾的文件。在这个文件夹下的程序为系统默认的组件,自己安装的软件将不会出现在这里,而是/data/文件夹中。

 

system/bin     

 这个目录下的文件都是系统的本地程序,从bin文件夹名称可以看出是binary二进制的程序,里面主要是Linux系统自带的组件。 system/etc       从文件夹名称来看保存的都是系统的配置文件,比如APN接入点设置等核心配置。

 

system/fonts  

字体文件夹,除了标准字体和粗体、斜体外可以看到文件体积最大的可能是中文字库,或一些unicode字库。

 

system/framework 

主要是一些核心的文件,从后缀名为jar可以看出是是系统平台框架。

 

system/lib       

lib目录中存放的主要是系统底层库,如平台运行时库。

 

system/media 

铃声音乐文件夹,除了常规的铃声外还有一些系统提示事件音

 

system/usr     

用户文件夹,包含共享、键盘布局、时间区域文件等。

 

通过\out\target\product\prj\ installed-files.txt文件可以查看system.img加压后包括的目录信息。

 

4.3  ./mk recoveryimage

 

1)     编译生成的文件

boot.img、ramdisk.img、ramdisk-recovery.img、recovery.img。

 

2)     修改recovery相关代码时用到此编译命令

alps/bootable/recovery/

alps/mediatek/customer/$project_name$/recovery/

......

 

3)     Recovery.img内容

 

Bootloader 会根据某些判定条件(比如按某个特殊键)决定是否进入 recovery 模式。Recovery 模式会装载 recovery 分区, 该分区包含recovery.img。recovery.img 包含了标准内核(和boot.img中的内核相同)以及recovery 根文件系统


图7

可以看出recovery.img和boot.img的差别在于boot.img包含的根文件系统对应于ramdisk.img,而recovery.img包含的根文件系统对应于ramdisk-recovery.img

 

recovery.img的生成过程可看build\core\Makefile下面相关部分:


[plain]  view plain copy
  1. recovery_kernel :=$(INSTALLED_KERNEL_TARGET) # same as a non-recovery system  
  2. recovery_ramdisk:= $(PRODUCT_OUT)/ramdisk-recovery.img  
  3. ………………………..  
  4. INSTALLED_RECOVERYIMAGE_TARGET:= $(PRODUCT_OUT)/recovery.img  
  5. …………………………..  
  6. INTERNAL_RECOVERYIMAGE_ARGS:= \  
  7.        $(addprefix --second,$(INSTALLED_2NDBOOTLOADER_TARGET)) \  
  8.        --kernel $(recovery_kernel) \  
  9.        --ramdisk $(recovery_ramdisk)  
  10. ……………………  
  11.    
  12. $(INSTALLED_RECOVERYIMAGE_TARGET):$(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \  
  13.               $(INSTALLED_RAMDISK_TARGET)\  
  14.               $(INSTALLED_BOOTIMAGE_TARGET)\  
  15.               $(recovery_binary)\  
  16.               $(recovery_initrc)$(recovery_kernel) \  
  17.               $(INSTALLED_2NDBOOTLOADER_TARGET)\  
  18.               $(recovery_build_prop)$(recovery_resource_deps) \  
  19.               $(recovery_fstab)\  
  20.               $(recovery_gzip)$(recovery_sec_ko) \  
  21.               $(RECOVERY_INSTALL_OTA_KEYS)  
  22.        @echo----- Making recovery image ------  
  23.        rm-rf $(TARGET_RECOVERY_OUT)  
  24.        mkdir-p $(TARGET_RECOVERY_OUT)  
  25.        mkdir-p $(TARGET_RECOVERY_ROOT_OUT)  
  26.        mkdir-p $(TARGET_RECOVERY_ROOT_OUT)/etc  
  27.        mkdir-p $(TARGET_RECOVERY_ROOT_OUT)/tmp  
  28.        echoCopying baseline ramdisk...  
  29.        cp-R $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT)  
  30.        rm-f $(TARGET_RECOVERY_ROOT_OUT)/init*.rc  
  31.        echoModifying ramdisk contents...  
  32.        rm-rf $(TARGET_RECOVERY_ROOT_OUT)/res  
  33.        cp-f $(recovery_initrc) $(TARGET_RECOVERY_ROOT_OUT)/  
  34.        cp-f $(recovery_gzip) $(TARGET_RECOVERY_ROOT_OUT)/sbin/gzip  
  35.        cp-f $(recovery_sec_ko) $(TARGET_RECOVERY_ROOT_OUT)/  
  36.        cp-f $(recovery_binary) $(TARGET_RECOVERY_ROOT_OUT)/sbin/  
  37.        cp-rfL $(recovery_resources_common) $(TARGET_RECOVERY_ROOT_OUT)/  
  38.        $(foreachitem,$(recovery_resources_private), \  
  39.          cp -rf $(item) $(TARGET_RECOVERY_ROOT_OUT)/)  
  40.        $(foreachitem,$(recovery_fstab), \  
  41.          cp -f $(item)$(TARGET_RECOVERY_ROOT_OUT)/etc/recovery.fstab)  
  42.        cp$(RECOVERY_INSTALL_OTA_KEYS) $(TARGET_RECOVERY_ROOT_OUT)/res/keys  
  43.        cat$(INSTALLED_DEFAULT_PROP_TARGET) $(recovery_build_prop) \  
  44.                >$(TARGET_RECOVERY_ROOT_OUT)/default.prop  
  45.        $(MKBOOTFS)$(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk)  
  46.        mediatek/build/tools/mkimage$(PRODUCT_OUT)/ramdisk-recovery.img RECOVERY >$(PRODUCT_OUT)/ramdisk_recovery.img  
  47.        mv$(PRODUCT_OUT)/ramdisk_recovery.img $(PRODUCT_OUT)/ramdisk-recovery.img  
  48.        $(MKBOOTIMG)$(INTERNAL_RECOVERYIMAGE_ARGS) --output $@  
  49.        @echo----- Made recovery image -------- $@  
  50.        $(hide)$(call assert-max-image-size,$@,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE),raw)  
  51. 用到的一些环境变量在build\core\envsetup.mk文件下:  
  52. TARGET_RECOVERY_OUT := $(PRODUCT_OUT)/recovery  
  53. TARGET_RECOVERY_ROOT_OUT :=$(TARGET_RECOVERY_OUT)/root  
  54. TARGET_RECOVERY_ROOT_OUT  
  55.    
  56. TARGET_ROOT_OUT := $(PRODUCT_OUT)/root  

可知ramdisk.img对应的目录和ramdisk-recovery.img对应的目录差如下:


图8

 

 

4.4  ./mk secroimage

 

1)     编译生成的文件

secro.img。

 

2)     修改secro相关代码时用到此编译命令

alps/mediatek/source/secro/

alps/mediatek/customer/$project_name$/secro/

 

3)     secro.img内容

MTK6577+Android编译之android_第5张图片 

图9

1)     复制\mediatek\custom\prj\secro目录到\out\target\product\prj\secro目录

2)     \out\target\product\prj\secro文件夹打包成为secro.img

 

详细的生成过程见build\core\Makefile相关部分

 

BUILT_SECROIMAGE_TARGET:= $(PRODUCT_OUT)/secro.img

 

4.5  ./mk factoryimage

 

1)     编译生成的文件

factory.bin。

 

2)     修改factory相关代码时用到此编译命令

alps/mediatek/customer/$project_name$/factory/

alps/mediatek/customer/common/factory/

alps/mediatek/source/factory/

......

 

3)     Factory.bin内容

Factory.bin大小为0,先来看build\core\Makefile相关文件:

 

[plain]  view plain copy
  1. factory_ramdisk :=$(PRODUCT_OUT)/ramdisk-factory.img  
  2.    
  3. INSTALLED_FACTORYIMAGE_TARGET:= $(PRODUCT_OUT)/factory.img  
  4. ………………….  
  5.    
  6. .PHONY:factoryimage  
  7. factoryimage:$(INSTALLED_FACTORYIMAGE_TARGET)  
  8.        @mediatek/build/tools/mkimage$(PRODUCT_OUT)/ramdisk-factory.img ROOTFS > $(PRODUCT_OUT)/factory.bin  

可知factory.bin是ramdisk-factory.img打上ROOTFS标识后的文件,接着来看build\core\envsetup.mk下面的信息:

[plain]  view plain copy
  1. TARGET_FACTORY_OUT:= $(PRODUCT_OUT)/factory  
  2. TARGET_FACTORY_ROOT_OUT:= $(TARGET_FACTORY_OUT)/root  

可知其意向是把\out\target\product\prj\factory\root目录打包生成为ramdisk-factory.img的,但并没有存在此目录,所以最后生成的factory.bin为0。

 

4.6  ./mk userdataimage

生成out\target\product\prj\data目录,并将此文件夹打包生成userdata.img,但是实际上没有看到对应的userdata.img更新,好像只有./mk new时才生成新的。

 

userdata.img挂载到 /data 下的镜像,它包含了应用及用户相关的数据。

 

4.7  ./mk cacheimage

提示make: *** No rule to make target`cacheimage'.  Stop.

 

参考链接:

《Android_Build_System_for_customer》

Android编译系统详解(一)

http://blog.csdn.net/mr_raptor/article/details/7539978

Android.mk的用法和基础

http://blog.csdn.net/zhandoushi1982/article/details/5316669

 

Android OTA升级之三:生成recovery.img

http://blog.csdn.net/zjujoe/article/details/6230575/

你可能感兴趣的:(MTK6577+Android编译之android)