失效链接处理 |
Android OTA代码单分?PDF 下蝲
本站整理下蝲Q?/strong>
链接Q?a target="_blank">https://pan.baidu.com/s/1y-8Z9h5krR9c2cxj-J6HDg
提取码:jvz1
相关截图Q?/strong>
![]()
主要内容Q?/strong>
Android 代码OTAQ?nbsp; 已验证?/div>
一、OTA版本~译及包制作QAndroid 11代码ZQ?/div>
./build.sh dist -j32 2>&1 | tee build.txt
?/div>
source build/envsetup.sh
lunch qssi-userdebug /lito-userdebug
./build.sh dist -qssi_only -j24 2>&1 | tee build.txt
./build.sh dist -target_only -j24 2>&1 | tee build.txt
./build.sh dist -merge_only -j24 2>&1 | tee build.txt
相关的OTA包会生成在:
out\dist\merged-qssi_lito-ota.zip
--->OTA全量升?/div>
out\dist\merged-qssi_lito-target_files.zip
--->OTA差分升原始?/div>
差分包制作命令参考:./build/tools/releasetools/ota_from_target_files -v --block -p out/host/linux-x86 -i \
oldrignal.zip newrignal.zip update.zip
OTA升包文件结构AB模式与非AB模式有明昄差别Q?nbsp;
OTA 差分升包目录结?AB模式Q?/div>
META-INF文g夹:
OTA 差分升包目录结?非AB模式Q?/div>
META-INF文g夹:
PATCH文g夹:
注意Q工L(fng)录时是要用make otapackage?./build.sh dist~译后生成的IMGQ否则差分升U是无法成功的?/div>
二、OTA包升U过E分析(旧升U模式)QAndroid 11 A/B模式没有走这个流E?/div>
OTA重启前流E?
1. APK或SD升最l都会调用到RecoverySystem.installPackageҎ(gu)Q?/div>
Frameworks/base/core/java/android/os/RecoverySystem.java
public static void installPackage(Context context, File packageFile, boolean processed)
throws IOException {
synchronized (sRequestLock) {
LOG_FILE.delete();
// Must delete the file in case it was created by system server.
UNCRYPT_PACKAGE_FILE.delete();
String filename = packageFile.getCanonicalPath();
Log.w(TAG, "!!! REBOOTING TO INSTALL " + filename + " !!!");
// If the package name ends with "_s.zip", it's a security update.
boolean securityUpdate = filename.endsWith("_s.zip");
// If the package is on the /data partition, the package needs to
// be processed (i.e. uncrypt'd). The caller specifies if that has
// been done in 'processed' parameter.
if (filename.startsWith("/data/")) {
if (processed) {
if (!BLOCK_MAP_FILE.exists()) {
Log.e(TAG, "Package claimed to have been processed but failed to find "
+ "the block map file.");
throw new IOException("Failed to find block map file");
}
} else {
FileWriter uncryptFile = new FileWriter(UNCRYPT_PACKAGE_FILE);
try {
uncryptFile.write(filename + "\n");
} finally {
uncryptFile.close();
}
// UNCRYPT_PACKAGE_FILE needs to be readable and writable
// by system server.
if (!UNCRYPT_PACKAGE_FILE.setReadable(true, false)
|| !UNCRYPT_PACKAGE_FILE.setWritable(true, false)) {
Log.e(TAG, "Error setting permission for " + UNCRYPT_PACKAGE_FILE);
}
BLOCK_MAP_FILE.delete();
}
// If the package is on the /data partition, use the block map
// file as the package name instead.
filename = "@/cache/recovery/block.map";
}
final String filenameArg = "--update_package=" + filename + "\n";
final String localeArg = "--locale=" + Locale.getDefault().toLanguageTag() + "\n";
final String securityArg = "--security\n";
String command = filenameArg + localeArg;
if (securityUpdate) {
command += securityArg;
}
RecoverySystem rs = (RecoverySystem) context.getSystemService(
Context.RECOVERY_SERVICE);
if (!rs.setupBcb(command)) { //------>向bootloader contral block写入相关的参数值command
throw new IOException("Setup BCB failed");
}
// Having set up the BCB (bootloader control block), go ahead and reboot
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
String reason = PowerManager.REBOOT_RECOVERY_UPDATE;
// On TV, reboot quiescently if the screen is off
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
DisplayManager dm = context.getSystemService(DisplayManager.class);
if (dm.getDisplay(DEFAULT_DISPLAY).getState() != Display.STATE_ON) {
reason += ",quiescent";
}
}
pm.reboot(reason);//---> 以reason=”recovery-update”方式重启q入recovery模式
throw new IOException("Reboot failed (no permissions?)");
}
}
|