Android的Recovery模式调用过程

1.概述

    Android的Recovery模式用于系统软件升级。

    将特定的update.zip文件置于特定的存储位置,比如/flash/update.zip,或者/mnt/storage/update.zip,然后通过Recovery模式重启进行软件升级。

    从应用程序调用到JAVA框架层,再到Kernel中的JNI的调用,以及底层的C语言本地代码的调用过程来看,除了与boolloader相关的系统调用reboot需要跟相应的硬件平台关联起来之外,其他都是通用的调用过程。

    不同硬件平台所需要做的修改在于,驱动层面需要对arch_reset函数重定向,如:

    void (*arch_reset)(char, const char *) = rk30_arch_reset

2.函数调用过程

 RecoverSystem.java

       PowerManager pm= (PowerManager) context.getSystemService(Context.POWER_SERVICE);

       pm.reboot("recovery");

-->

\frameworks\base\services\java\com\android\server\PowerManagerService.java

   public voidreboot(String reason)

       ShutdownThread.reboot(mContext,finalReason, false);

-->

\frameworks\base\services\java\com\android\server\pm\ShutdownThread.java

   shutdownInner(context,confirm);

-->

   beginShutdownSequence(context);

-->

   run

-->

   rebootOrShutdown

-->

   PowerManagerService.lowLevelReboot(reason);

-->

\frameworks\base\services\java\com\android\server\PowerManagerService.java

   nativeReboot();

-->

   private staticnative void nativeReboot(String reason) throws IOException;

-->

\frameworks\base\services\jni\com_android_server_PowerManagerService.cpp

   android_reboot(ANDROID_RB_RESTART2,0, (char *) chars);

 

\system\core\libcutils\android_reboot.c

        caseANDROID_RB_RESTART2:

            ret =__reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,

                          LINUX_REBOOT_CMD_RESTART2, arg);

-->

\kernel\kernel\sys.c

SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsignedint, cmd,

       void __user *,arg)

{

kernel_restart(buffer);

}

-->

machine_restart(cmd);

-->

\kernel\arch\arm\kernel\process.c

arm_pm_restart(reboot_mode, cmd);

-->

   arm_machine_restart(char str, const char *cmd)

-->

   /*

    * Now call the architecture specific rebootcode.

    */

   调用每个平台自己的重启函数。因为这里的重启的参数的使用与各个平台具体的bootloader相关,只能由各个平台自己去实现。

   arch_reset(mode,cmd);

-->

\kernel\arch\arm\mach-rk30\reset.c

   void(*arch_reset)(char, const char *) = rk30_arch_reset;

static void rk30_arch_reset(char mode, const char *cmd)

{

   u32 boot_flag = 0;

   u32 boot_mode =BOOT_MODE_REBOOT;

 

   if (cmd) {

       if(!strcmp(cmd, "loader") || !strcmp(cmd, "bootloader"))

          boot_flag =SYS_LOADER_REBOOT_FLAG + BOOT_LOADER;

       elseif(!strcmp(cmd, "recovery"))

          boot_flag =SYS_LOADER_REBOOT_FLAG + BOOT_RECOVER;

       else if(!strcmp(cmd, "charge"))

          boot_mode =BOOT_MODE_CHARGE;

   } else {

       if(system_state != SYSTEM_RESTART)

          boot_mode =BOOT_MODE_PANIC;

   }

   writel_relaxed(boot_flag,RK30_PMU_BASE + PMU_SYS_REG0);    // forloader

   writel_relaxed(boot_mode,RK30_PMU_BASE + PMU_SYS_REG1);    // forlinux

   dsb();

   /* disable remap */

   writel_relaxed(1<< (12 + 16), RK30_GRF_BASE + GRF_SOC_CON0);

   /* pll enter slowmode */

   writel_relaxed(PLL_MODE_SLOW(APLL_ID)| PLL_MODE_SLOW(CPLL_ID) | PLL_MODE_SLOW(GPLL_ID), RK30_CRU_BASE +CRU_MODE_CON);

   dsb();

   writel_relaxed(0xeca8,RK30_CRU_BASE + CRU_GLB_SRST_SND);

   dsb();

}

 


 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值