目錄
◆ 概述
● 幾種啟動模式
● MISC分區
● CACHE分區
● 幾種系統升級方式
◆ Recovery升級
● 升級包構成,簽名,制作
● 升級腳本
● 升級過程
◆ OTA升級
● 升級包構成,制作
● 升級腳本
● 升級過程
◆ fastboot升級
◆ ADB升級
幾種啟動模式
◆ 正常模式
進入方式:不按鍵,正常啟動時進入.
文件:loader + Uboot + Boot.img + system.img
◆ recovery模式
進入方式:特殊組合按鍵,reboot recovery命令, MISC分區
指令,系統崩潰.
文件:loader + Uboot + recovery.img
recovery.img = Boot.img + recovery(/sbin/recorey)
操作界面在recovery程序中提供
◆ fastboot模式
進入方式:特殊組合按鍵
文件:loader + Uboot
操作界面在Uboot中提供
MISC分區
◆存放Bootloader Control Block (BCB),是bootloader與Recovery的通信接口.啟動時bootloader中讀取BCB, 根據指令決定啟動方式.
struct bootloader_message {char command[32];char status[32];char recovery[1024];
};
command:“boot-recovery”:指示bootloader應該進入recovery modestatus:完成相應的更新后,bootloader將執行結果寫入到這個字段recovery:該文件的內容格式如下:
“recovery\n
<recovery command>\n
<recovery command>”
是一個字符串,以“recovery\n”開頭,后面一行對應一個recovery命令,與/cache/recovery/command文件相對應
CACHE分區
recovery通過/cache/recovery/目錄下的三個文件與主系統通信,增量升級過程中也需要借助于/cache分區存放臨時文件.進入recovery 程序后,會先讀取BCB的內容,失敗再讀取/cache/recovery/command的內容,以決定是否有特殊命令要執行
◆ /cache/recovery/command:recovery命令,由主系統寫入,每一行就是一條命令,是以下命令的組合:● --wipe_data:擦除用戶數據,會清除/data分區和/cache分區● --wipe_cache :擦除/cache分區● --update_package=path: 表示要進行OTA升級,recovery使用路徑為path的OTA升級包● --send_intent=anystring: 傳遞的intent
◆ /cache/recovery/log:recovery模式在工作中的log輸出,再次進入recovery的時候會清除
◆ /cache/recovery/intent:recovery傳遞給主系統的intent,在recovery結束時將定義的intent字符串寫入到/cache/recovery/intent中
幾種系統升級方式
◆ recovery升級也稱為卡刷,全量升級,按鍵進入recovery后執行存儲卡上下載好的升級包依賴于能正常進入recovery, 升級包大
◆ OTA升級OTA(over the air),也稱為在線升級,增量升級,一般為按鍵進入recovery后執行下載好的升級包,也可下載全量升級包依賴于系統運行正常, 需要網絡,升級包小,操作便捷
◆ fastboot升級也稱線刷,進入fastboot模式后,機器連接USB線,使用PC上的燒錄工具將鏡像文件燒錄到機器,類似于USB燒錄依賴于Uboot正常即可,升級數據量大,操作相對復雜,穩定性高
◆ ADB升級也稱一鍵刷機,通過ADB,使用flash_image程序,借助于PC將鏡像文件更新到機器依賴于ADB開放和能正常root, 升級數據量大,操作簡單,穩定性低
recovery升級
recovery升級-升級包構成
◆system/, data/, recovery/:這些目錄對應需要升級的分區,分別對應system,data,recovery分區的內容
◆boot.img這些文件對應需要升級的文件,升級過程中會直接覆蓋鏡像
◆MANIFEST.MF簽名相關文件.遍歷包中的所有文件,對非文件夾非簽名文件的文件,逐個生成SHA1的數字簽名信息,再用Base64進行編碼
◆CERT.SF簽名相關文件.對Manifest文件,使用SHA1-RSA算法,用私鑰進行簽名
◆CERT.RSA簽名相關文件.文件中保存了公鑰、所采用的加密算法等信息
◆metadata文件是描述設備信息及環境變量的元數據。主要包括一些編譯選項,時間戳以及設備型號等
◆otacert簽名公鑰,對應xxx.x509.pem文件
◆update-binary是一個二進制文件,相當于一個腳本解釋器,能夠識別updater-script中描述的操作.對應源碼位于:bootable/recovery/updater/
◆updater-script此文件是一個腳本文件,具體描述了更新過程。我們可以根據具體情況編寫該腳本來適應我們的具體需求.
recovery升級-升級包簽名
◆update.zip的簽名
$ java –jar out/host/linux/framework/signapk.jar –w /build/target/product/security/xxx.x509.pem /build/target/product/security/xxx.pk8 update_signed.zipupdate.zip
recovery升級包在進行簽名時使用signapk.jar工具,與APK簽名使用的工具相同,但與APK簽名不同的是,使用了-w選項,指對整個文件進行簽名,使用-w簽名的包在結尾是6個特征字節
制作包使用私鑰對update.zip進行簽名,recovery中使用對應的公鑰進行驗證,recovery 代碼里面使用的公鑰(/res/keys)是按照RSAPublicKey數據結構存儲。這個數據是通過RSAPublicKey工具(dumpkey.jar)從制作出來的x509證書文件中獲得
◆破解簽名驗證
在update.zip簽名時使用的公鑰/私鑰對不是公開的key(比如testkey)的情況下,因為用戶無法得到正確的私鑰,而且recovery使用的公鑰隨recovery.img發布,所以很難偽造簽名來通過recovery驗證
變通的做法是給系統刷入一個使用testkey公鑰進行驗證recovery.img,而包對應使用testkey進行簽名.或者刷入一個不進行簽名驗證的recovery.img
recovery升級-制作升級包
◆制作方式有手動制作和自動制作兩種
● 手動制作
準備好升級文件和目錄,手動寫腳本updater-script,copy腳本解
釋程序update-binary(system/bin/updater),打包成zip文件,然后
使用signapk.jar對zip文件進行簽名
● 自動制作
源碼根目錄執行 make otapackage,out目錄下生成全量升級包,
名稱為: out/target/product/h600s/h600s-ota-eng.lsg.zip
第一步:編譯Makefile,生成原始包
第二步:在原始包的基礎上使用python腳本生成全量升級包,
python腳本路徑:build/tools/releasetools/ota_from_target_files,
入口函數是:WriteFullOTAPackage(input_zip,output_zip)
☆注意:
make otapackage 會對整個系統進行編譯,要注意這里的編譯方式
與正常編譯的一致性
recovery升級-腳本
◆assert(condition)
如果condition參數的計算結果為False,則停止腳本執行,否則繼續
執行腳本。
◆show_progress(frac,sec)
frac表示進度完成的數值,sec表示整個過程的總秒數。主要用與顯示
UI上的進度條。
示例: show_progress(0.1, 10);
下面的操作可能進行10s,完成后進度條前進0.1(也就是10%)
◆format(fs_type, partition_type, location, fs_size,mount_point)
fs_type,文件系統類型,取值一般為“vfat”或“ext4”。
Partition_type,分區類型,一般取值為“MTD”或則“EMMC”。
location,設備路徑
fs_size,等于0表示格式化整個分區,大于0表示按指定大小格式化,
小于0表示在分區最后保留一定大小
◆mount(fs_type,partition_type,location,mount_point)
前兩個參數同上,location要掛載的設備,mount_point掛載點。作用:掛載一個文件系統到指定的掛載點。
◆ui_print(const char *fmt, …)
作用:將字符串顯示到屏幕上
示例:ui_print(“update system.img…”);
◆symlink(target,src1,src2,……,srcN)
target,字符串類型,是符號連接的目標。SrcX代表要創建的符號連接的目標點。
示例:symlink(“mksh”, “/system/bin/sh”);
◆set_perm(uid,gid,mode,file1,file2,……,fileN)
作用是設置單個文件或則一系列文件的權限,最少要指定一個文件
示例:set_perm(0, 1000, 0750, “/system/bin/tc”);
◆package_extract_file(srcfile_path,desfile_paht)
srcfile_path,要提取的文件,desfile_path,提取文件的目標位置。
示例:package_extract_file(“boot.img”,”/tmp/boot.img”)將升級包中的boot.img文件拷貝到內存文件系統的/tmp下
◆package_extract_dir(src_path,destination_path)src_path,
要提取的目錄,destination_path目標目錄。作用:從升級包內,提取目錄到指定的位置。
示例:package_extract_dir(“system”,”/system”)
◆write_raw_image(src-image,partition):
src-image源鏡像文件,partition,目標分區。作用:將鏡像寫入目標分區。
示例:write_raw_image(“/sdcard/system.img”,“system”);將system.img鏡像寫入到系統的system分區。
◆/etc/recovery.fstab
提供各分區對應的設備, 及分區文件系統類型. 非編譯生成, 在board目錄是掛載和燒錄的關鍵.
例如(H8):
/xboot emmc /dev/block/platform/jzmmc.0/by-name/xboot/boot emmc /dev/block/platform/jzmmc.0/by-name/boot/recovery emmc /dev/block/platform/jzmmc.0/by-name/recovery/system ext4 /dev/block/platform/jzmmc.0/by-name/system/data ext4 /dev/block/platform/jzmmc.0/by-name/data/cache ext4 /dev/block/platform/jzmmc.0/by-name/cache/misc emmc /dev/block/platform/jzmmc.0/by-name/misc/mnt/sdcard2 vfat /dev/block/platform/jzmmc.0/by-name/storage1/mnt/sdcard0 vfat /dev/block/platform/jzmmc.0/by-name/storage2/mnt/sdcard1 vfat /dev/block/mmcblk2p1 /dev/block/mmcblk2/sdcard auto /dev/block/mmcblk2p1 /dev/block/mmcblk2
recovery升級-過程
源碼路徑: bootable/recovery/
升級update.zip的核心函數在 install_package()
■1.ensure_path_mount()
先判斷所傳的update.zip包路徑所在的分區是否已經掛載。如果沒有則先掛載。
■2.load_keys()
加載公鑰源文件,路徑位于/res/keys。這個文件在Recovery鏡像的根文件系統中。
■3.verify_file()
對升級包update.zip包進行簽名驗證。
■4.mzOpenZipArchive()
打開升級包,并將相關的信息拷貝到一個臨時的ZipArchinve變量中。這一步并未對我們的update.zip包解壓。
■5.try_update_binary()
在這個函數中才是對我們的update.zip升級的地方。這個函數一開始先根據我們上一步獲得的zip包信息
以及升級包的絕對路徑將update_binary文件拷貝到內存文件系統的/tmp/update_binary中。以便后面使用。
■6.fork()
創建子進程。其中的子進程主要負責執行binary(execv(binary,args),即執行我們的安裝命令腳本.
父進程負責接受子進程發送的命令去更新ui顯示(顯示當前的進度)。子父進程間通信依靠管道。
腳本里描述的過程大概有以下幾步:
■1.比較時間戳,匹配機型設備信息,條件不符則停止腳本運行
■2.顯示進度條起始位置
■3.格式化system分區并掛載
■4.提取包中的recovery以及system目錄下的內容到系統的/system下
■5.為/system下的文件建立符號連接, 設置屬性
■6.更新包中的boot.img
■7.如果要更新/data分區,則掛載/data,并更新/data分區的內容
■8.如果有其他的鏡像文件比如uboot等需要更新,則更新這些鏡像文件
■9.卸載已掛載的分區,腳本結束
recovery升級-定制
◆1. 修改releasetool.py
recovery在 build/tools/releasetools/common.py 中提供了一個類
(DeviceSpecificParams)用于自定義一些功能
具體的功能實現放在名為releasetool.py的文件中,這個文件放在具體
的board文件夾下,比如build/target/board/h600s/releasetools.py
可以自定義的功能有: FullOTA_InstallBegin, FullOTA_InstallEnd,
IncrementalOTA_InstallBegin, IncrementalOTA_InstallEnd
◆2. 直接修改build/tools/releasetools/ 下的文件
OTA升級
OTA升級-升級包構成
OTA升級-制作升級包
◆OTA不一定是升級增量包,但一般指增量升級.增量升級只能在指定兩個版本間進行升級.
◆制作增量包以原始包(target包)為基礎,將第一次生成的target包暫時稱為target-A.zip,將第二次生成的target包暫時稱為target-B.zip
◆利用這兩個target包,生成增量包
./build/tools/releasetools/ota_from_target_files -v -i target-A.zip target-B.zip ota-A-B-incremental.zip
☆注意
1. 發布版本時要注意備份原始包,且保證原始包的數據與下單版本完全一致;
2. 目標版本(target-B.zip)比基礎版本(target-A.zip)少的文件會在基礎版本中刪除,目標版本(target-B.zip)比基礎版本(target-A.zip)多的文件會在基礎版本中增加,要保持一致性不要輕易刪除文件;
3. 同一模塊的名字在兩個版本中不要隨意改變;
OTA升級-原始包
◆make otapackage過程中生成,路徑如下:out/target/product/h600s/obj/PACKAGING/target_files_intermediates/h600starget_files-eng.lsg.zip
◆單個原始包(target包)可以生成全量包(full包),兩個原始包(target包)可以生成增量包(increment包),都使用到腳本:
build/tools/releasetools/ota_from_target_files
包含的基本目錄:
◆BOOT/, RECOVERY/
包括RAMDISK/和kernel
◆SYSTEM/
system目錄的原始拷貝
◆OTA/
applypatch等升級中用到的程序
◆META/
文件清單及文件對應權限,分區類型和大小等信息
OTA升級-腳本
在增量升級中特有的:
◆apply_patch_check(file, [sha1_1, …])
檢查文件file的SHA1值是不是多個中的一個,前面的為目標SHA1值
示例:
apply_patch_check(“/system/app/BBKSettings.apk”,
“8bca5488310c0625bc4498285c37e5fecd873b3a”,
“48f4d405351a334feea17a52ad118c346f64a253”)
◆apply_patch(srcfile, tgtfile, tgtsha1, tgtsize, sha1_1, patch_1, …)
srcfile:源文件,tgtfile:目標文件,“-“表示與源文件相同
tgtsha1:目標文件SHA1值,tgtsize:目標文件長度
作用:利用patch文件將源文件升級到目標文件
示例:apply_patch(”/system/app/BBKSettings.apk”, “-”,
8bca5488310c0625bc4498285c37e5fecd873b3a, 911757,
48f4d405351a334feea17a52ad118c346f64a253,
package_extract_file(“patch/system/app/BBKSettings.apk.p”));
OTA升級-過程
◆總體上分為兩步:
第一步:OTA升級程序根據機器版本從服務器上找出最適合的升級包,然后下載到本地,調用RecoverySystem類的方法,使機器重啟進入recovery,并將升級包路徑寫入cache分區
第二步:進入recovery界面后,獲取升級包路徑,自動開始執行升級過程,升級完畢后自動重啟進入正常啟動模式
腳本里描述的過程大概有以下幾步:
■1.檢查系統版本,機型信息,系統版本必須是兩個版本中的一個
■2.檢查文件是否一致(“Verifying current system…”),當前系統中的文件必須與起始版本文件的sha1 值一致,調用apply_patch_check進行檢查
■3.刪除不需要的文件(“Removing unneeded files…”),調用delete,只存在于起始版本或目標版本中的文件在這里先刪除
■4.應用差量文件(“Patching system files…”),調用apply_patch,使用.p文件升級起始版本的文件為目標版本的文件
■5.增加新文件(“Unpacking new files…”),將增加的新文件拷貝到機器上,注意對于目標版本中新增的文件,通常會刪除舊文件在增加新文件
■6.修改文件權限,結束
增量升級一個文件的過程如下(applypatch):
■1.獲取目標文件的 sha1 值(target_sha1),此值會與當前文件的sha1值進行比較,如果一致就證明文件已于目標文件一致,無需升級直接返回
■2.載入源文件(source_file)(注意是一次性載入),如果載入失敗,則試圖入/cache/saved.file文件
■3.判斷源文件所在分區是否有足夠剩余空間,如果沒有足夠空間則將源文件復制到cache分區,保存為/cache/saved.file,并刪除源文件
■4.在源文件目錄建立".patch"的文件,使用patch工具進行增量
■5.增量完畢后,計算文件(.patch)的 sha1 值并與target_sha1比較。如果一致就證明增量成功,成功則將".patch"去掉.patch; 失敗則重試,達到設定的重試次數后,認為失敗,返回結果
fastboot
fastboot界面示例
◆操作步驟:
1.準備好fastboot數據包和fastboot PC工具
2.機器關機,按組合鍵進入fastboot模式
3.機器連接USB線,安裝好USB驅動,在PC工具上能看到識別設備成功
4.從PC工具上選擇fastboot數據包,開始升級
當機器進入fastboot模式,PC上fastboot驅動安裝完畢后,就能通過fastboot命令操作機器
◆fastboot devices
作用:輸出所有連接的設備
◆fastboot erase
作用:擦除分區
示例:fastboot erase system; fastboot erase userdata
◆flashboot flash [ ]
作用:刷入鏡像
示例: fastboot flash system system.img
◆fastboot reboot
作用:重啟
ADB升級
◆大多數的一鍵刷機工具都是采用此種方式,機器要開放ADB且能獲得root權限
◆需要借助flash_image程序,flash_image程序由bootable/recovery/下編譯生成
◆示例:
adb root
adb shell mount /sdcard
adb shell push c:\system.img /mnt/sdcard/
adb shell flash_image system /mnt/sdcard/system.img
adb shell reboot
☆注意
此種方式不穩定,變磚可能性較大
Root
◆為什么要Root?
擁有root權限后,可以訪問,修改,刪除系統的任何文件.刪除預置應用,修改系統等
◆怎么樣Root?
最終目標是將su放入/system/bin/下,安裝授權管理程序Superuser.apk
◆Root的方式?
實現方式有多種,包括利用Android漏洞,利用recovery刷入此兩文件.
利用Android漏洞的方式不一定對所有機型都適用
◆怎樣刷第三方ROM?
刷入一個不做簽名驗證或利用testkey做簽名驗證的recovery. 刷入recovery的
方式可以利用fastboot, 也可以使用adb方式
覺得本文對您有用,麻煩點贊、關注、收藏,您的肯定是我創作的無限動力,謝謝!!!