淘姐妹

淘姐妹

recovery 流程学习总结(二)

电脑 0
recovery,recover,recovery进入后仍需密码,recover真的能恢复吗视频拨伤i
1引言 1.1目的 对学习的Android Recovery模式及OTA升级过程进行总结,为加深理解和防止以后遗忘,所以写这篇文档进行一个总结和梳理,以便日后查阅回顾。文档主要包括两部分,第一部分为恢复出厂设置过程,第二部分为Recovery模式下OTA升级包安装过程的分析以及遇到的问题总结。 1.2适用范围 1.3参考文献 内容主要来自自己的总结,知识库中的经验案例和网络上的一些公开资源。 2.进入recovery的方式 我公司手机一般正确手动进入recovery模式的方式为:power+【【微信】】+volume down 手机开机后,硬件系统上电,完成一系列的初始化工作:CPU、串口、终端、timer、DDR等硬件设备,然后加载bootloader,为后面内核加载做准备工作。在系统启动初始化完成后系统检测进入哪一种工作模式,这一部分代码的源文件在\bootable\bootloader\lk\app\aboot\aboot.c文件的aboot_init()函数中: 检测用户关机方式,如果是强制关机,则进入normal_boot模式 if (is_user_force_reset()) goto normal_boot; 检测音量上下键的按键状态,判断进入何种模式: if (keys_get_state(KEY_【【微信】】) && keys_get_state(KEY_【【微信】】)) { 【【微信】】(ALWAYS,"dload mode key se【【微信】】 "); if (set_download_mode(EMERGENCY_DLOAD)) { 【【微信】】(CRITICAL,"dload mode not supported by target "); } else { reboot_device(DLOAD); 【【微信】】(CRITICAL,"Failed to reboot into dload mode "); } boot_into_fastboot = true; } if (!boot_into_fastboot) { if (keys_get_state(KEY_HOME) || keys_get_state(KEY_【【微信】】)) boot_into_recovery = 1; if (!boot_into_recovery && (keys_get_state(KEY_BACK) || keys_get_state(KEY_【【微信】】))) boot_into_fastboot = true; } 根据以上代码,开机过程中按home键或者音量上键会进入recovery模式,按back键或者音量下键会进入fastboot模式。 如果没有组合键(代码中称为magic key)按下,则会检测SMEM(在后头会介绍SMEM的的来源) 中的reboot_mode 变量值。 reboot_mode = check_reboot_mode(); hard_reboot_mode = 【【微信】】(); if (reboot_mode == RECO【【微信】】 || hard_reboot_mode == RECO【【微信】】) { boot_into_recovery = 1; } else if(reboot_mode == FASTBOOT_MODE || hard_reboot_mode == FASTBOOT_HARD_RESET_MODE) { boot_into_fastboot = true; } else if(reboot_mode == ALARM_BOOT || hard_reboot_mode == RTC_HARD_RESET_MODE) { boot_reason_alarm = true; } reboot_mode 可取的值宏定义为: #define FASTBOOT_MODE 0x77665500 #define RECO【【微信】】 0x【【QQ微信】】 而check_reboot_mode 函数定义在\bootable\bootloader\lk arget\ msm8916\init.c 中,函数先读取restart_reason_addr 处的数值,定义为0x2A05F65C,没有采取宏定义,属于不规范的表达。读取完该值之后,在该地址写入0x00,即擦除其内容,以防下次启动又进入recovery 模式。 【【微信】】_mode(void) { 【【微信】】on = 0; restart_reason = readl(RESTART_REASON_ADDR); writel(0x00, RESTART_REASON_ADDR); 【【微信】】 restart_reason; } 如果reboot_mode 的值没有定义,则读取MISC 分区的BCB 进行判断,调用函数为reco【【微信】】(),其实现在\bootable\bootloader\lk\app\aboot\recovery.c 中,函数先通过调用get_reco【【微信】】()把BCB 读到reco【【微信】】 结构体中,再读取其command 字段。如果字段是“boot-recovery”,则进入recovery 模式;如果是“update-radio”,则进入固件升级流程。 系统启动流程分析图 如果以上条件皆不满足,则进入正常启动序列,系统会加载boot.img文件,然后加载kernel,在内核加载完成之后,会根据内核的传递参数寻找android的第一个用户进程,即init进程,该进程根据init.rc以及init.$(hardware).rc脚本文件来启动android的必要的服务,直到完成android系统的启动。 当进入recovery模式时,系统加载的是recovery.img文件,该文件内容与boot.img类似,也包含了标准的内核和根文件系统。但是recovery.img为了具有恢复系统的能力,比普通的boot.img目录结构中: 1、多了/res/images目录,在这个目录下的图片是恢复时我们看到的背景画面。 2、多了/sbin/recovery二进制程序,这个就是恢复用的程序。 3、/sbin/adbd不一样,recovery模式下的adbd不支持shell。 4、初始化程序(init)和初始化配置文件(init.rc)都不一样。这就是系统没有进入图形界面而进入了类似文本界面,并可以通过简单的组合键进行恢复的原因。 与正常启动系统类似,也是启动内核,然后启动文件系统。在进入文件系统后会执行/init,init的配置文件就是 /init.rc。这个配置文件位于bootable/recovery/etc/init.rc。查看这个文件我们可以看到它做的事情很简单: 1) 设置环境变量。 2) 建立etc连接。 3) 新建目录,备用。 4) 挂载文件系统。 5) 启动recovery(/sbin/recovery)服务。 6) 启动adbd服务(用于调试)。 上文所提到的fastboot模式,即命令或SD卡烧写模式,不加载内核及文件系统,此处可以进行工厂模式的烧写。 综上所述,有三种进入recovery模式的方法,分别是开机时按组合键,写SMEM中的reboot_mode变量值,以及写位于MISC分区的BCB中的command字段。 除了上述方式还可以通过命令进入recovery模式࿱【【微信】】.恢复出厂设置的过程 在setting-->备份与重置--->恢复出厂设置--->重置手机--->手机关机--->开机--->进行恢复出厂的操作--->开机流程。 恢复出厂设置其实是擦除用户数据分区,同时删除缓存区。在系统设置中选择“恢复出厂设置”选项后, APK 会发出一个广播:“andro【【微信】】.action.MASTER_CLEAR”,接收者是MasterClearReceiver 类,在收到广播之后会开启一个新线程: public 【【微信】】(final Context context, final Intent intent) { …… // The reboot call is blocking, so we need to do it on another thread. Thread thr = new Thread("Reboot") { @O【【微信】】() { try { Reco【【微信】】.【【微信】】(context, shutdown, reason); Log.wtf(TAG, "Still running after master clear?!"); } catch (IOException e) { Slog.e(TAG, "Can't perform master clear/factory reset", e); } catch (SecurityException e) { Slog.e(TAG, "Can't perform master clear/factory reset", e); } } }; thr.start(); } 线程中调用了\【【微信】】\base\core\jav【【微信】】\os\Reco【【微信】】.java类的【【微信】】方法: public static void 【【微信】】(Context context, boolean shutdown, String reason) throws IOException { UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); if (um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) { throw new SecurityException("Wiping data is not allowed for this user."); } final Condition【【微信】】 = new Condition【【微信】】(); Intent intent = new Intent("andro【【微信】】.action.MASTER_CLEAR_NOTIFICATION"); intent.addFlags(Intent.FLAG_RECEI【【微信】】); context.sendOrderedBroadcastAsUser(intent, UserHandle.OWNER, android.Manifest.permission.MASTER_CLEAR, new BroadcastReceiver() { @O【【微信】】 public 【【微信】】(Context context, Intent intent) { condition.open(); } }, null, 0, null, null); // Block until the ordered broadcast has completed. condition.block(); String shutdownArg = null; if (shutdown) { shutdownArg = "--shutdown_after"; } String reasonArg = null; if (!TextUtils.isEmpty(reason)) { reasonArg = "--reason=" + sanitizeArg(reason); } final String localeArg = "--locale=" + Locale.getDefault().toString(); bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg); } 最终调用bootCommand(context, shutdownArg, "--wipe_data", reasonArg, localeArg);完成擦除数据的操作 bootCommand()函数分析: pri【【微信】】mmand(Context context, String... args) throws IOException { RECO【【微信】】.mkdirs(); // In case we need it COMMAND_FILE.delete(); // In case it's not writable LOG_FILE.delete(); FileWriter command = new FileWriter(COMMAND_FILE); //将参数逐行写入command文件中 try { for (String arg : args) { if (!TextUtils.isEmpty(arg)) { command.write(arg); command.write(" "); } } } finally { command.close(); } // 写入cache/recovery/command文件中后,继续执行reboot的后续操作 PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); //这里执行reboot操作进入recovery模式 pm.reboot(PowerManager.REBOOT_RECOVERY); 【【微信】】("Reboot failed (no permissions?)"); } 这里进入recovery模式的入口在于: 【【微信】】\base\core\jav【【微信】】\os\PowerManager.java public void 【【微信】】ring reason) { try { mSe【【微信】】(false, reason, true); } catch (RemoteException e) { } } IPowerManager.aidl文件中的方法如下: 【【微信】】(boolean confirm, String reason, boolean wait); 其中对应的实现位于PowerManagerService.java中的内部类【【微信】】中: private final class 【【微信】】 extends IPowerManager.Stub { …… @O【【微信】】 // Binder call public 【【微信】】(boolean confirm, String reason, boolean wait) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null); if (PowerManager.REBOOT_RECOVERY.【【微信】】(reason)) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null); } 【【微信】】 = Binder.clearCallingIdentity(); try { shutdownO【【微信】】ernal(false, confirm, reason, wait); } finally { Binder.restoreCallingIdentity(ident); } } …… } bootCommand()经过如下调用后最终到调用到本地JNI 接口【【微信】】ive(),就是\【【微信】】\base\core\jni\android_os_Power.cpp 中的android_os_Powe【【微信】】 函数。 具体的调用流程如下: 该函数继续调用\system\core\libcutils\android_reboot.c 中的int android_reboot(int cmd, int flags UNUSED, char *arg),该函数根据第一个参数的不同走向不同的分支, switch (cmd) { case ANDROID_RB_RESTART: ret = reboot(RB_AUTOBOOT); break; case ANDROID_RB_POWEROFF: ret = reboot(RB_POWER_OFF); break; case ANDROID_RB_RESTART2: ret = syscall(__NR_reboot,LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, arg); break; default: ret = -1; } 相关宏定义见\kernel\include\linux\reboot.h。在reboot.h中定义的函数实现在kernel/kernel/sys.c中的函数 SYSCALL_DEFINE4():为了避免误操作而进入 recovery模式,该函数首先检测所谓的魔法参数,之后判断启动命令,如果是 LINUX_REBOOT_CMD_RESTART2,表示用所给的命令字符串重启系统。调用关系如下: 可以看出,虽然经过了层层调用,但始终有一个内容为“recovery”的字符串参数没有被丢弃过,最后传给了arch_reset(mode, cmd),最终在这里使用: 可以看到,当参数为“recovery”时,会给restart_reason 地址处写入0x【【QQ微信】】。 在代码里有: 45: #define RESTART_REASON_ADDR 0x65C 247: restart_reason = MSM_IMEM_BASE + RESTART_REASON_ADDR; 在\kernel\arch\arm\mach-msm\include\mach\msm_iomap-8x60.h 中有 所以restart_reason 的实际物理地址是0x2A05F000+0x65C =0x2A05F65C,在之前讲到手机启动时࿰【【微信】】 函数会检测SMEM 中的reboot_mode 变量值以判断进入何种工作方式,该函数中读取内存地址0x2A05F65C,这正是arch_reset 函数写入restart_reason 的地址。这样调用pm.reboot(“recovery”) 函数后,最终实现了重启后进入recovery 模式。 4.OTA工作过程 升级所需要的update.zip包来源有两种,一是OTA在线下载(一般下载到/CACHE分区),二是手动拷贝到SD卡中。不论是哪种方式获得update.zip包,在进入Recovery模式前,都未对这个zip包做处理。只是在重启之前将zip包的路径告诉了Recovery服务。 当选择升级后,调用Reco【【微信】】类的installPackage()方法。这个函数首先根据传过来的包文件,获取这个包文件的绝对路径filename,然后将其拼成arg = “--update_package=” + filename,最终会被写入到BCB中,这个就是重启进入Recovery模式后,Recovery服务要进行的操作。它被传递到函数bootCommand(context,arg),在这个函数中才是Main System在重启前真正做的准备。 Recovery模式主要的执行过程在bootable/recovery/recovery.cpp中,这里从main()函数开始分析 Int main(int argc,char **argv){ …… …… } 具体执行流程如下: 1、在函数的开始会对argc和argv进行检验: if (argc == 2 && strcmp(argv[1], "--adbd") == 0) { adb_main();//进入adb_main()过程 【【微信】】 0; } 2、 Load and parse 【【微信】】 /etc/recovery.fstab. 【【微信】】e();该函数在bootable/recovery/roots.cpp中,主要功能根据“etc/recovery.fstab”加载和解析分区; 3、确保参数传入的分区是被成功mounted,成功时返回0 ensure_path_mounted(LAST_LOG_FILE);// LAST_LOG_FILE =”/cache/recovery/last_log”存放的是最近一次的recovery过程的日志文件; 4、重命名日志, Rename last_log -> last_log.1 -> last_log.2 -> ... -> last_log.$max rotate_last_logs(KEEP_LOG_COUNT);// KEEP_LOG_COUNT不超过10个 5、获取命令参数,get_args(&argc, &argv); 如果参数未提供,则从BCB(Bootloader Control Block)查找,如果BCB中也没有则尝试在命令文件中查找相应的命令,将最终获得的参数写进BCB中,直到finish_recovery被调用完,再从BCB中清除。 6、根据命令参数给控制变量赋值,具体过程见如下的循环: while ((arg = getopt_long(argc, argv, "", 【【微信】】, NULL)) != -1) { switch (arg) { case 's': 【【微信】】 = optarg; break; case 'u': update_package = optarg; break; case 'w': wipe_data = wipe_cache = 1; break; case 'c': wipe_cache = 1; break; case 't': show_text = 1; break; case 'x': jus

pr脱机文件恢复方法 pr脱机文件删除了怎么恢复

pr脱机文件如何链接到原素材?,pr脱机文件什么意思,pr脱机文件怎么找回来,pr脱机文件怎么重新连接

本文为大家介绍pr脱机文件怎么恢复?(pr脱机文件怎么恢复出厂设置),下面和小编一起看看详细内容吧。

在使用pr的时候,如果用户想要恢复离线文件,用户只需要在时间轴中点击一个素材,选中后右击,然后选择替换素材,比较方便。

pr使用技巧:在使用pr时,如果用户要导入视频,可以在打开pr后双击面板,然后选择要导入的视频,也可以直接拖拽视频进行编辑进入面板,这样就导入成功了。

在使用pr剪辑视频时,如果用户希望导出的视频质量尽可能好,可以将帧率和码率设置得尽可能高,但需要注意的是,如果这两个值偏高,导出的视频占用大量内存。

如果用户导入的视频是MTS格式,可能没有声音。因此,在编辑MTS格式的视频之前,用户最好修改视频格式后再进行编辑。

数据拓展:Premiere提供采集、剪辑、校色、音频美化、加字幕、输出、DVD刻录等一整套流程,与其他Adobe软件高效集成,足以完成剪辑、制作中的所有遭遇,和工作流程挑战,以满足创作高质量作品的要求。

好了,pr脱机文件怎么恢复?(pr脱机文件怎么恢复出厂设置)的介绍到这里就结束了,想知道更多相关资料可以收藏我们的网站。