Android OTA代码简单分析.docx
- 文档编号:6088893
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:18
- 大小:85.07KB
Android OTA代码简单分析.docx
《Android OTA代码简单分析.docx》由会员分享,可在线阅读,更多相关《Android OTA代码简单分析.docx(18页珍藏版)》请在冰豆网上搜索。
AndroidOTA代码简单分析
本章主要记录AndroidOTA升级相关的内容,仅供参考。
Android代码OTA:
已验证。
一、OTA版本编译及包制作(Android11代码为例)
./build.shdist-j322>&1|teebuild.txt
或
sourcebuild/envsetup.sh
lunchqssi-userdebug/lito-userdebug
./build.shdist-qssi_only-j242>&1|teebuild.txt
./build.shdist-target_only-j242>&1|teebuild.txt
./build.shdist-merge_only-j242>&1|teebuild.txt
相关的OTA包会生成在:
out\dist\merged-qssi_lito-ota.zip
--->OTA全量升级包
out\dist\merged-qssi_lito-target_files.zip
--->OTA差分升级原始包
差分包制作命令参考:
./build/tools/releasetools/ota_from_target_files-v--block-pout/host/linux-x86-i\
oldrignal.zipnewrignal.zipupdate.zip
OTA升级包文件结构AB模式与非AB模式有明显的差别:
OTA差分升级包目录结构-AB模式:
META-INF文件夹:
OTA差分升级包目录结构-非AB模式:
META-INF文件夹:
PATCH文件夹:
注意:
工具烧录时是要用makeotapackage或./build.shdist编译后生成的IMG,否则差分升级是无法成功的。
二、OTA包升级过程分析(旧升级模式);Android11A/B模式没有走这个流程。
OTA重启前流程:
1.APK或SD升级最终都会调用到RecoverySystem.installPackage方法:
Frameworks/base/core/java/android/os/RecoverySystem.java
publicstaticvoidinstallPackage(Contextcontext,FilepackageFile,booleanprocessed)
throwsIOException{
synchronized(sRequestLock){
LOG_FILE.delete();
//Mustdeletethefileincaseitwascreatedbysystemserver.
UNCRYPT_PACKAGE_FILE.delete();
Stringfilename=packageFile.getCanonicalPath();
Log.w(TAG,"!
!
!
REBOOTINGTOINSTALL"+filename+"!
!
!
");
//Ifthepackagenameendswith"_s.zip",it'sasecurityupdate.
booleansecurityUpdate=filename.endsWith("_s.zip");
//Ifthepackageisonthe/datapartition,thepackageneedsto
//beprocessed(i.e.uncrypt'd).Thecallerspecifiesifthathas
//beendonein'processed'parameter.
if(filename.startsWith("/data/")){
if(processed){
if(!
BLOCK_MAP_FILE.exists()){
Log.e(TAG,"Packageclaimedtohavebeenprocessedbutfailedtofind"
+"theblockmapfile.");
thrownewIOException("Failedtofindblockmapfile");
}
}else{
FileWriteruncryptFile=newFileWriter(UNCRYPT_PACKAGE_FILE);
try{
uncryptFile.write(filename+"\n");
}finally{
uncryptFile.close();
}
//UNCRYPT_PACKAGE_FILEneedstobereadableandwritable
//bysystemserver.
if(!
UNCRYPT_PACKAGE_FILE.setReadable(true,false)
||!
UNCRYPT_PACKAGE_FILE.setWritable(true,false)){
Log.e(TAG,"Errorsettingpermissionfor"+UNCRYPT_PACKAGE_FILE);
}
BLOCK_MAP_FILE.delete();
}
//Ifthepackageisonthe/datapartition,usetheblockmap
//fileasthepackagenameinstead.
filename="@/cache/recovery/block.map";
}
finalStringfilenameArg="--update_package="+filename+"\n";
finalStringlocaleArg="--locale="+Locale.getDefault().toLanguageTag()+"\n";
finalStringsecurityArg="--security\n";
Stringcommand=filenameArg+localeArg;
if(securityUpdate){
command+=securityArg;
}
RecoverySystemrs=(RecoverySystem)context.getSystemService(
Context.RECOVERY_SERVICE);
if(!
rs.setupBcb(command)){//------>向bootloadercontralblock写入相关的参数值command
thrownewIOException("SetupBCBfailed");
}
//HavingsetuptheBCB(bootloadercontrolblock),goaheadandreboot
PowerManagerpm=(PowerManager)context.getSystemService(Context.POWER_SERVICE);
Stringreason=PowerManager.REBOOT_RECOVERY_UPDATE;
//OnTV,rebootquiescentlyifthescreenisoff
if(context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)){
DisplayManagerdm=context.getSystemService(DisplayManager.class);
if(dm.getDisplay(DEFAULT_DISPLAY).getState()!
=Display.STATE_ON){
reason+=",quiescent";
}
}
pm.reboot(reason);//--->以reason=”recovery-update”方式重启进入recovery模式
thrownewIOException("Rebootfailed(nopermissions?
)");
}
}
2.rs.setupBcb跟踪
最终会跟到services下的RecoverySystemService.java文件setupBcb函数
frameworks/base/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
publicbooleansetupBcb(Stringcommand){
if(DEBUG)Slog.d(TAG,"setupBcb:
["+command+"]");
synchronized(sRequestLock){
returnsetupOrClearBcb(true,command);
}
}
.............
privatebooleansetupOrClearBcb(booleanisSetup,Stringcommand){
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY,null);
finalbooleanavailable=checkAndWaitForUncryptService();
if(!
available){
Slog.e(TAG,"uncryptserviceisunavailable.");
returnfalse;
}
//设置ctl.start属性,启动setup-bcb服务
if(isSetup){
mInjector.systemPropertiesSet("ctl.start","setup-bcb");
}else{
mInjector.systemPropertiesSet("ctl.start","clear-bcb");
}
//Connecttotheuncryptservicesocket.//连接uncrypt服务
UncryptSocketsocket=mInjector.connectService();
if(socket==null){
Slog.e(TAG,"Failedtoconnecttouncryptsocket");
returnfalse;
}
try{
//SendtheBCBcommandsifit'stosetupBCB.
if(isSetup){
socket.sendCommand(command);
}
//Readthestatusfromthesocket.
intstatus=socket.getPercentageUncrypted();
//Ackreceiptofthestatuscode.uncryptwaitsfortheackso
//thesocketwon'tbedestroyedbeforewereceivethecode.
socket.sendAck();
if(status==100){
Slog.i(TAG,"uncrypt"+(isSetup?
"setup":
"clear")
+"bcbsuccessfullyfinished.");
}else{
//Errorin/system/bin/uncrypt.
Slog.e(TAG,"uncryptfailedwithstatus:
"+status);
returnfalse;
}
}catch(IOExceptione){
Slog.e(TAG,"IOExceptionwhencommunicatingwithuncrypt:
",e);
returnfalse;
}finally{
socket.close();
}
returntrue;
}
SystemProperties.set(“ctl.start”,“setup-bcb”),通过这种方式来启动服务,而后连接服务,向其中发送BCBcommand。
OTA升级重启前,主要的操作是对升级包进行处理的过程,对升级包提前处理的原因是因为在进入recovery模式进行升级时无法加载升级包所在的分区。
在重启前的主要操作如下:
1.通过SystemProperties设置属性(setup-bcb),向BCB中设置升级的Command;
2.通过SystemProperties设置属性(uncrypt),开启uncrypt服务,将升级包生成一系列的block块,recovery可以读取block.map文件并获取这个文件的数据作为升级包;
3.uncrypt完成后,重启。
OTA升级重启后
1.重启后bootRom到recovery模式
这个过程不是很清楚,之前bootable/bootloader/lk代码about.c里调转,
Android11的是bootable/bootloader/edk2
2.recovery启动
bootable/recovery/recovery_main.cpp
intmain(intargc,char**argv){
......................
ui->SetEnableFastbootdLogo(fastboot);
autoret=fastboot?
StartFastboot(device,args):
start_recovery(device,args);
.......................
switch(ret){
caseDevice:
:
SHUTDOWN:
ui->Print("Shuttingdown...\n");
Shutdown("userrequested,recovery");
break;
caseDevice:
:
SHUTDOWN_FROM_FASTBOOT:
ui->Print("Shuttingdown...\n");
Shutdown("userrequested,fastboot");
break;
.......................................................
}
Recovery.cpp
参考下这个文件最开始的注释说明
/*
*Therecoverytoolcommunicateswiththemainsystemthrough/cachefiles.
*/cache/recovery/command-INPUT-commandlinefortool,oneargperline
*/cache/recovery/log-OUTPUT-combinedlogfilefromrecoveryrun(s)
*
*Theargumentswhichmaybesuppliedinthemandfile:
*--update_package=path-verifyinstallanOTApackagefile
*--install_with_fuse-installtheupdatepackagewithFUSE.Thisallowsinstallationoflarge
*packagesonLP32builds.Sincethemmapwillotherwisefailduetooutofmemory.
*--wipe_data-eraseuserdata(andcache),thenreboot
*--prompt_and_wipe_data-prompttheuserthatdataiscorrupt,withtheirconsenteraseuser
*data(andcache),thenreboot
*--wipe_cache-wipecache(butnotuserdata),thenreboot
*--show_text-showtherecoverytextmenu,usedbysomebootloader(e.g.http:
//b/36872519).
*--set_encrypted_filesystem=on|off-enables/diasablesencryptedfs
*--just_exit-donothing;exitandreboot
*
*Aftercompleting,weremove/cache/recovery/commandandreboot.
*Argumentsmayalsobesuppliedinthebootloadercontrolblock(BCB).
*Theseimportantscenariosmustbesafelyrestartableatanypoint:
*
*FACTORYRESET
*1.userselects"factoryreset"
*2.mainsystemwrites"--wipe_data"to/cache/recovery/command
*3.mainsystemrebootsintorecovery
*4.get_args()writesBCBwith"boot-recovery"and"--wipe_data"
*--afterthis,rebootingwillrestarttheerase--
*5.erase_volume()reformats/data
*6.erase_volume()reformats/cache
*7.FinishRecovery()erasesBCB
*--afterthis,rebootingwillrestartthemainsystem--
*8.main()callsreboot()tobootmainsystem
*
*OTAINSTALL
*1.mainsystemdownloadsOTApackageto/cache/some-filename.zip
*2.mainsystemwrites"--update_package=/cache/some-filename.zip"
*3.mainsystemrebootsintorecovery
*4.get_args()writesBCBwith"boot-recovery"and"--update_package=..."
*--afterthis,rebootingwillattempttoreinstalltheupdate--
*5.InstallPackage()attemptstoinstalltheupdate
*NOTE:
thepackageinstallmustitselfberestartablefromanypoint
*6.FinishRecovery()erasesBCB
*--afterthis,rebootingwill(tryto)restartthemainsystem--
*7.**ifinstallfailed**
*7a.PromptAndWait()showsanerroriconandwaitsfortheuser
*7b.theuserreboots(pullingthebattery,etc)intothemainsystem
*/
Device:
:
BuiltinActionstart_recovery(Device*device,conststd:
:
vector : string>&args){ ............................. boolshould_use_fuse=false; if(! SetupPackageMount(update_package,&should_use_fuse)){ //---->检查挂载zip所在分区,一般情况下是/data分区 LOG(INFO)<<"Failedtosetupthepackageaccess,skippinginstallation"; status=INSTALL_ERROR; }elseif(install_with_fuse||should_use_fuse){ LOG(INFO)<<"Installingpackage"< status=InstallWithFuseFromPath(update_package,ui); }elseif(automemory_package=Package: : CreateMemoryPackage( update_package, std: : bind(&RecoveryUI: : SetProgress,ui,std: : placeholders: : _1)); memory_package! =nullptr){ status=InstallPackage(memory_package.get(),update_package,should_wipe_cache, retry_count,ui); }else{ //
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android OTA代码简单分析 OTA 代码 简单 分析