MTK6577采用的內存芯片為H9TP32A4GDMCPR,包括4GB的eNAND和512MB的 LPDDR2,先升級為H9TP32A8JDMCPR,包括4GB的eNAND和1GB的LPDDR2
?
先來看MTK源代碼樹概觀圖:
圖1
由圖1可知編譯的入口是makeMtk文件,其采用perl語言編寫的,包裝了編譯命令,下面來看編譯系統的概述:
圖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 plaincopy
LOGDIR????????=?$(MKTOPDIR)/out/target/product?? ??? ANDROID_IMAGES???:=?$(LOGDIR)/$(PROJECT)/system.img?\?? ???????????????????$(LOGDIR)/$(PROJECT)/boot.img?\?? ???????????????????$(LOGDIR)/$(PROJECT)/recovery.img?\?? ???????????????????$(LOGDIR)/$(PROJECT)/secro.img?\?? ???????????????????$(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 plaincopy
android:?? ifeq?($(ACTION),?)?? ???????$(hide)?/usr/bin/perlmediatek/build/tools/mtkBegin.pl?$(FULL_PROJECT)?? endif?? ??? ifneq($(DR_MODULE),)?? ???ifneq?($(ACTION),?clean)?? ???????$(hide)?echo?building?android?moduleMODULE=$(DR_MODULE)?? ???????$(hide)?perlmediatek/build/tools/javaoptgen.pl?$(PRJ_MF)?$(OPTR_MF)?? ???????$(MAKECMD)?$(DR_MODULE)?? ???else?? ???????$(hide)?echo?cleaning?android?moduleMODULE=$(DR_MODULE)?? ???????$(hide)?$(MAKECMD)?clean-$(DR_MODULE)?? ???endif?? else?? ???????$(hide)?echo?$(SHOWTIME)?$(SHOWBUILD)ing$@...?? ???????$(hide)?echo?-e?\\t\\t\\t\\b\\b\\b\\bLOG:$(S_MODULE_LOG)?? ifeq($(SHOWBUILD),?build)?? ???????$(hide)?perlmediatek/build/tools/javaoptgen.pl?$(PRJ_MF)?$(OPTR_MF)?$(DEAL_STDOUT)?? endif?? ???????$(hide)?$(MAKECMD)?$(ACTION)$(DEAL_STDOUT)?&&?\?? ????????$(call?chkImgSize,$(ACTION),$(PROJECT),$(SCATTER_FILE),$(if?$(strip$(ACTION)),$(CHECK_IMAGE),$(ANDROID_IMAGES)),$(DEAL_STDOUT),&&)?\?? ????????$(SHOWRSLT)?$${PIPESTATUS[0]}?$(MODULE_LOG)?$(ACTION)?||?\?? ????????$(SHOWRSLT)?$${PIPESTATUS[0]}?$(MODULE_LOG)?$(ACTION)?? ??? ifeq?($(ACTION),?)?? ???????$(hide)?/usr/bin/perlmediatek/build/tools/mtkFinalize.pl?$(PROJECT)?$(MTK_PLATFORM)$(MTK_EMMC_SUPPORT)?? endif?? 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 plaincopy
INSTALLED_BOOTIMAGE_TARGET:=?$(PRODUCT_OUT)/boot.img?? BUILT_RAMDISK_TARGET:=?$(PRODUCT_OUT)/ramdisk.img?? ??? INSTALLED_RAMDISK_TARGET:=?$(BUILT_RAMDISK_TARGET)?? ??? ifeq?"""$(CUSTOM_BUILD_VERNO)"?? ??CUSTOM_BUILD_VERNO?:=?$(BUILD_NUMBER)?? ??CUSTOM_BUILD_VERNO?:=?$(substeng.$(USER).,,$(CUSTOM_BUILD_VERNO))?? endif?? ??? #-----------------------------------------------------------------?? #?the?boot?image,which?is?a?collection?of?other?images.?? INTERNAL_BOOTIMAGE_ARGS:=?\?? ???????$(addprefix?--second,$(INSTALLED_2NDBOOTLOADER_TARGET))?\?? ???????--kernel?$(INSTALLED_KERNEL_TARGET)?\?? ???????--ramdisk?$(INSTALLED_RAMDISK_TARGET)?? ………………………?? ifneq?"""$()"?? ??INTERNAL_BOOTIMAGE_ARGS?+=?--board$(CUSTOM_BUILD_VERNO)?? Endif?? ………………………………………?? $(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 plaincopy
if(write(fd,&hdr,?sizeof(hdr))?!=?sizeof(hdr))?goto?fail;?? ????if(write_padding(fd,?pagesize,sizeof(hdr)))?goto?fail;?? ??? ????if(write(fd,?kernel_data,?hdr.kernel_size)!=?hdr.kernel_size)?goto?fail;?? ????if(write_padding(fd,?pagesize,hdr.kernel_size))?goto?fail;?? ??? ????if(write(fd,?ramdisk_data,hdr.ramdisk_size)?!=?hdr.ramdisk_size)?goto?fail;?? ????if(write_padding(fd,?pagesize,hdr.ramdisk_size))?goto?fail;?? ??? ????if(second_data)?{?? ????????if(write(fd,?second_data,hdr.second_size)?!=?hdr.second_size)?goto?fail;?? ????????if(write_padding(fd,?pagesize,hdr.ramdisk_size))?goto?fail;?? }??
\system\core\mkbootimg\bootimg.h目錄下boot_img_hdr定義了文件頭信息:
[cpp]?view plaincopy
typedef?structboot_img_hdr?boot_img_hdr;?? ??? #define?BOOT_MAGIC"ANDROID!"?? #defineBOOT_MAGIC_SIZE?8?? #defineBOOT_NAME_SIZE?16?? #defineBOOT_ARGS_SIZE?512?? ??? structboot_img_hdr?? {?? ????unsigned?char?magic[BOOT_MAGIC_SIZE];?? ??? ????unsigned?kernel_size;???? ????unsigned?kernel_addr;???? ??? ????unsigned?ramdisk_size;??? ????unsigned?ramdisk_addr;??? ??? ????unsigned?second_size;???? ????unsigned?second_addr;???? ??? ????unsigned?tags_addr;?????? ????unsigned?page_size;?????? ????unsigned?unused[2];?????? ??? ????unsigned?char?name[BOOT_NAME_SIZE];??? ????? ????unsigned?char?cmdline[BOOT_ARGS_SIZE];?? ??? ????unsigned?id[8];??? };??
Boot.img的組成借用bootimg.h下給出的解釋:
圖4
?
2)?????mkbootfs打包生成ramdisk.img
圖5
?
在build/core/Makefile文件中看下面主要的相關部分:
[plain]?view plaincopy
##################################################################?? #?Targets?forboot/OS?images?? ##################################################################?? ??? #-----------------------------------------------------------------?? #?the?ramdisk?? INTERNAL_RAMDISK_FILES:=?$(filter?$(TARGET_ROOT_OUT)/%,?\?? ???????$(ALL_PREBUILT)?\?? ???????$(ALL_COPIED_HEADERS)?\?? ???????$(ALL_GENERATED_SOURCES)?\?? ???????$(ALL_DEFAULT_INSTALLED_MODULES))?? ??? BUILT_RAMDISK_TARGET:=?$(PRODUCT_OUT)/ramdisk.img?? ??? #?We?just?buildthis?directly?to?the?install?location.?? INSTALLED_RAMDISK_TARGET:=?$(BUILT_RAMDISK_TARGET)?? $(INSTALLED_RAMDISK_TARGET):$(MKBOOTFS)?$(INTERNAL_RAMDISK_FILES)?|?$(MINIGZIP)?? ???????$(call?pretty,"Target?ram?disk:$@")?? ???????$(hide)?$(MKBOOTFS)?$(TARGET_ROOT_OUT)?|$(MINIGZIP)?>?$@?? ifneq?($(strip$(TARGET_NO_KERNEL)),true)????????? ???????$(hide)?mediatek/build/tools/mkimage$(PRODUCT_OUT)/ramdisk.img?ROOTFS?>?$(PRODUCT_OUT)/ramdisk_android.img?? ???????mv?$(PRODUCT_OUT)/ramdisk.imgmediatek/source/kernel/trace32/$(TARGET_PRODUCT)_ramdisk.img?? ???????$(hide)?mv$(PRODUCT_OUT)/ramdisk_android.img?$(PRODUCT_OUT)/ramdisk.img?? 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
圖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 plaincopy
recovery_kernel?:=$(INSTALLED_KERNEL_TARGET)?#?same?as?a?non-recovery?system?? recovery_ramdisk:=?$(PRODUCT_OUT)/ramdisk-recovery.img?? ………………………..?? INSTALLED_RECOVERYIMAGE_TARGET:=?$(PRODUCT_OUT)/recovery.img?? …………………………..?? INTERNAL_RECOVERYIMAGE_ARGS:=?\?? ???????$(addprefix?--second,$(INSTALLED_2NDBOOTLOADER_TARGET))?\?? ???????--kernel?$(recovery_kernel)?\?? ???????--ramdisk?$(recovery_ramdisk)?? ……………………?? ??? $(INSTALLED_RECOVERYIMAGE_TARGET):$(MKBOOTFS)?$(MKBOOTIMG)?$(MINIGZIP)?\?? ??????????????$(INSTALLED_RAMDISK_TARGET)\?? ??????????????$(INSTALLED_BOOTIMAGE_TARGET)\?? ??????????????$(recovery_binary)\?? ??????????????$(recovery_initrc)$(recovery_kernel)?\?? ??????????????$(INSTALLED_2NDBOOTLOADER_TARGET)\?? ??????????????$(recovery_build_prop)$(recovery_resource_deps)?\?? ??????????????$(recovery_fstab)\?? ??????????????$(recovery_gzip)$(recovery_sec_ko)?\?? ??????????????$(RECOVERY_INSTALL_OTA_KEYS)?? ???????@echo-----?Making?recovery?image?------?? ???????rm-rf?$(TARGET_RECOVERY_OUT)?? ???????mkdir-p?$(TARGET_RECOVERY_OUT)?? ???????mkdir-p?$(TARGET_RECOVERY_ROOT_OUT)?? ???????mkdir-p?$(TARGET_RECOVERY_ROOT_OUT)/etc?? ???????mkdir-p?$(TARGET_RECOVERY_ROOT_OUT)/tmp?? ???????echoCopying?baseline?ramdisk...?? ???????cp-R?$(TARGET_ROOT_OUT)?$(TARGET_RECOVERY_OUT)?? ???????rm-f?$(TARGET_RECOVERY_ROOT_OUT)/init*.rc?? ???????echoModifying?ramdisk?contents...?? ???????rm-rf?$(TARGET_RECOVERY_ROOT_OUT)/res?? ???????cp-f?$(recovery_initrc)?$(TARGET_RECOVERY_ROOT_OUT)/?? ???????cp-f?$(recovery_gzip)?$(TARGET_RECOVERY_ROOT_OUT)/sbin/gzip?? ???????cp-f?$(recovery_sec_ko)?$(TARGET_RECOVERY_ROOT_OUT)/?? ???????cp-f?$(recovery_binary)?$(TARGET_RECOVERY_ROOT_OUT)/sbin/?? ???????cp-rfL?$(recovery_resources_common)?$(TARGET_RECOVERY_ROOT_OUT)/?? ???????$(foreachitem,$(recovery_resources_private),?\?? ?????????cp?-rf?$(item)?$(TARGET_RECOVERY_ROOT_OUT)/)?? ???????$(foreachitem,$(recovery_fstab),?\?? ?????????cp?-f?$(item)$(TARGET_RECOVERY_ROOT_OUT)/etc/recovery.fstab)?? ???????cp$(RECOVERY_INSTALL_OTA_KEYS)?$(TARGET_RECOVERY_ROOT_OUT)/res/keys?? ???????cat$(INSTALLED_DEFAULT_PROP_TARGET)?$(recovery_build_prop)?\?? ???????????????>$(TARGET_RECOVERY_ROOT_OUT)/default.prop?? ???????$(MKBOOTFS)$(TARGET_RECOVERY_ROOT_OUT)?|?$(MINIGZIP)?>?$(recovery_ramdisk)?? ???????mediatek/build/tools/mkimage$(PRODUCT_OUT)/ramdisk-recovery.img?RECOVERY?>$(PRODUCT_OUT)/ramdisk_recovery.img?? ???????mv$(PRODUCT_OUT)/ramdisk_recovery.img?$(PRODUCT_OUT)/ramdisk-recovery.img?? ???????$(MKBOOTIMG)$(INTERNAL_RECOVERYIMAGE_ARGS)?--output?$@?? ???????@echo-----?Made?recovery?image?--------?$@?? ???????$(hide)$(call?assert-max-image-size,$@,$(BOARD_RECOVERYIMAGE_PARTITION_SIZE),raw)?? 用到的一些環境變量在build\core\envsetup.mk文件下:?? TARGET_RECOVERY_OUT?:=?$(PRODUCT_OUT)/recovery?? TARGET_RECOVERY_ROOT_OUT?:=$(TARGET_RECOVERY_OUT)/root?? TARGET_RECOVERY_ROOT_OUT?? ??? 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內容
?
圖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 plaincopy
factory_ramdisk?:=$(PRODUCT_OUT)/ramdisk-factory.img?? ??? INSTALLED_FACTORYIMAGE_TARGET:=?$(PRODUCT_OUT)/factory.img?? ………………….?? ??? .PHONY:factoryimage?? factoryimage:$(INSTALLED_FACTORYIMAGE_TARGET)?? ???????@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 plaincopy
TARGET_FACTORY_OUT:=?$(PRODUCT_OUT)/factory?? 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的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。