当前位置:   article > 正文

Android重启流程

android重启流程

我这边主要讲下android reboot走的流程及所设计的代码,直接从framework层开始。

framework会提供系统重启的接口:

代码路径:framework/base/core/java/android/os/Power.java

而嵌套的rebootNative(reason);其实是个native接口,其实现是在frameworks/base/core/jni/android_os_Power.cpp.

其中android_os_Power_reboot函数如下:

最终会调用到__reboot这个函数,其带4个参数,具体函数定义是在内核里kernel/sys.c

定义如下:

  1. SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
  2.         void __user *, arg)
  3. {
  4. .......
  5. .......
  6.     /* For safety, we require "magic" arguments. */
  7.     if (magic1 != LINUX_REBOOT_MAGIC1 ||                            //从这里可以看出其实magic1和magic2这两个参数其实没啥用,只是linux为了自身安全而带的两个参数
  8.         (magic2 != LINUX_REBOOT_MAGIC2 &&                       //重点在cmd这个参数
  9.                     magic2 != LINUX_REBOOT_MAGIC2A &&
  10.             magic2 != LINUX_REBOOT_MAGIC2B &&
  11.                     magic2 != LINUX_REBOOT_MAGIC2C))
  12.         return -EINVAL;
  13. .......
  14. .......
  15. .......

根据不同的cmd内核会选择做不同的事,停止、下电或者重启,我们这里主要讲重启的流程,那就接着从LINUX_REBOOT_CMD_RESTART2往下看吧

  1. case LINUX_REBOOT_CMD_HALT:    
  2.         kernel_halt();
  3.         do_exit(0);
  4.         panic("cannot halt");
  5.     case LINUX_REBOOT_CMD_POWER_OFF:
  6.         kernel_power_off();
  7.         do_exit(0);
  8.         break;
  9.     case LINUX_REBOOT_CMD_RESTART2:
  10.         if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {
  11.             ret = -EFAULT;
  12.             break;
  13.         }
  14.         buffer[sizeof(buffer) - 1] = '\0';
  15.         kernel_restart(buffer);
  16.         break;
  17. }

我们接着从kernel_restart(buffer);往下走,看调用

  1. kernel/sys.c:
  2. void kernel_restart(char *cmd)
  3. {
  4. ......
  5. ......   
  6.     machine_restart(cmd);
  7. ----->arch/arm/kernel/process.c:
  8. void machine_restart(char *cmd)
  9. {
  10.     arm_pm_restart(reboot_mode, cmd);
  11. }
  12. ----->arch/arm/kernel/process.c:
  13. void arm_machine_restart(char mode, const char *cmd)
  14. {
  15. ......
  16. ......
  17.     arch_reset(mode, cmd);
  18.     /*
  19.      * Whoops - the architecture was unable to reboot.
  20.      * Tell the user!
  21.      */
  22.     mdelay(1000);
  23.     printk("Reboot failed -- System halted\n");
  24.     while (1);
  25. }
  26. ----->arch/arm/mach-mmp/reset.c:
  27. void arch_reset(char mode, const char *cmd)
  28. {
  29.     if (cpu_is_pxa910() || cpu_is_pxa168())
  30.         pxa_arch_reset(mode, cmd);
  31.     else
  32.         return;
  33. }
  34. ----->arch/arm/mach-mmp/reset.c:
  35. static void pxa_arch_reset(char mode, const char *cmd)
  36. {
  37.     switch (mode) {
  38.     case 's':
  39.         /* Jump into ROM at address 0 */
  40.         cpu_reset(0);
  41.         break;
  42.     case 'w':
  43.     default:
  44.         do_wdt_reset(cmd);
  45.         break;
  46.     }
  47. }
  48. ----->arch/arm/mach-mmp/reset.c:
  49. static void do_wdt_reset(const char *cmd)
  50. {
  51. ......
  52. ......
  53.     if (cpu_is_pxa910())
  54.         watchdog_virt_base = CP_TIMERS2_VIRT_BASE;
  55.     else if (cpu_is_pxa168())
  56.         watchdog_virt_base = TIMERS1_VIRT_BASE;
  57.     else
  58.         return;
  59.     /* reset/enable WDT clock */
  60.     writel(0x7, MPMU_WDTPCR);
  61.     readl(MPMU_WDTPCR);
  62.     writel(0x3, MPMU_WDTPCR);
  63.     readl(MPMU_WDTPCR);
  64.     if (cpu_is_pxa910()) {
  65.         if (cmd && !strcmp(cmd, "recovery")) {
  66.             for (i = 0, backup = 0; i < 4; i++) {
  67.                 backup <<= 8;
  68.                 backup |= *(cmd + i);
  69.             }
  70.             do {
  71.                 writel(backup, REG_RTC_BR0);
  72.             } while (readl(REG_RTC_BR0) != backup);
  73. .......
  74. .......
  75. .......
  76. }

最终就会走到对应平台的reset函数里,根据不同平台会设置自己的一些寄存器参数,并且可以根据用户层传下的arg值来

做不同的事情,比如这里

  1. if (cmd && !strcmp(cmd, "recovery")) {
  2. for (i = 0, backup = 0; i < 4; i++) {
  3. backup <<= 8;
  4. backup |= *(cmd + i);
  5. }

如果传下来的字符串是recovery那么,就在RTC寄存器里设置某个特定值,当uboot里读取RTC寄存器的时候如果获取了这个特定值,那就可以起recovery这个动作了,大致流程是这样,希望对大家有帮助,偶人比较懒不喜欢多写注释,有兴趣的可以根据这个路径自己看代码理解。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/945198
推荐阅读
相关标签
  

闽ICP备14008679号