您的位置:首页 > 移动开发 > Android开发

android restart reason机制

2014-01-06 21:12 423 查看
Reboot传递参数,使得开机进入参数固定的模式(通常有我们熟悉的bootloader和recovery等),本质是在kernel
shutdown时会调用到restart,
将模式数值写到share memory中,那么在开机bootloader阶段,再去读取这块内存,boot进入指定的模式,要是匹配不起来就正常boot,以下是贴出的代码;
restart 2种方式:
a: android_reboot(ANDROID_RB_RESTART2, 0, "rtcalarm");//进入rtc alarm模式
b: adb reboot bootloader,adb reboot recovery;        //进入我们熟悉的bootloader和recorevy模式

Restar.c:

void *restart_reason;
/*函数将被赋值给machine restart指针*/
void msm_restart(char mode, const char *cmd)
{

#ifdef CONFIG_MSM_DLOAD_MODE

 /* This looks like a normal reboot at this point. */
 set_dload_mode(0);

 /* Write download mode flags if we're panic'ing */
 set_dload_mode(in_panic);

 /* Write download mode flags if restart_mode says so */
 if (restart_mode == RESTART_DLOAD) {
  set_dload_mode(1);
#ifdef CONFIG_LGE_CRASH_HANDLER
  writel(0x6d63c421, restart_reason);
  goto reset;
#endif
 }

 /* Kill download mode if master-kill switch is set */
 if (!download_mode)
  set_dload_mode(0);
#endif

 printk(KERN_NOTICE "Going down for restart now\n");

 pm8xxx_reset_pwr_off(1);

 if (cmd != NULL) {
  if (!strncmp(cmd, "bootloader", 10)) {
   __raw_writel(0x77665500, restart_reason);
  } else if (!strncmp(cmd, "recovery", 8)) {
   __raw_writel(0x77665502, restart_reason);
  } else if (!strncmp(cmd, "oem-", 4)) {
   unsigned long code;
   code = simple_strtoul(cmd + 4, NULL, 16) & 0xff;
   __raw_writel(0x6f656d00 | code, restart_reason);
  } else {
   __raw_writel(0x77665501, restart_reason);
  }
 } else {
  __raw_writel(0x77665501, restart_reason);
 }
#ifdef CONFIG_LGE_CRASH_HANDLER
 if (in_panic == 1)
  set_kernel_crash_magic_number();
reset:
#endif /* CONFIG_LGE_CRASH_HANDLER */

 __raw_writel(0, msm_tmr0_base + WDT0_EN);
 if (!(machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())) {
  mb();
  __raw_writel(0, PSHOLD_CTL_SU); /* Actually reset the chip */
  mdelay(5000);
  pr_notice("PS_HOLD didn't work, falling back to watchdog\n");
 }

 __raw_writel(1, msm_tmr0_base + WDT0_RST);
 __raw_writel(5*0x31F3, msm_tmr0_base + WDT0_BARK_TIME);
 __raw_writel(0x31F3, msm_tmr0_base + WDT0_BITE_TIME);
 __raw_writel(1, msm_tmr0_base + WDT0_EN);

 mdelay(10000);
 printk(KERN_ERR "Restarting has failed\n");
}

static int __init msm_restart_init(void)
{
#ifdef CONFIG_MSM_DLOAD_MODE
 atomic_notifier_chain_register(&panic_notifier_list, &panic_blk);
 dload_mode_addr = MSM_IMEM_BASE + DLOAD_MODE_ADDR;
#ifdef CONFIG_LGE_CRASH_HANDLER
 lge_error_handler_cookie_addr = MSM_IMEM_BASE +
  LGE_ERROR_HANDLER_MAGIC_ADDR;
#endif
 set_dload_mode(download_mode);
#endif
 msm_tmr0_base = msm_timer_get_timer0_base();
 restart_reason = MSM_IMEM_BASE + RESTART_REASON_ADDR;// restart_reason被赋值内存地址
 pm_power_off = msm_power_off;

 return 0;
}

lk:init.c
/*lk里面读出kernel写入的restart数值*/
unsigned check_reboot_mode(void)
{
 unsigned restart_reason = 0;
 void *restart_reason_addr = (void *)0x2A05F65C;

 /* Read reboot reason and scrub it */
 restart_reason = readl(restart_reason_addr);
 writel(0x00, restart_reason_addr);

 return restart_reason;
}

#define RECOVERY_MODE   0x77665502
#define FASTBOOT_MODE   0x77665500
#define ADB_REBOOT_MODE 0x77665501

/*check reboot mode*/
reboot_mode = check_reboot_mode();
 #if CONFIG_CHARING_WHILE_MECHINE_TRUN_OFF
 {
  extern unsigned int custom_power_on_charger(void);
  if(custom_power_on_charger() && reboot_mode && (reboot_mode!=FASTBOOT_MODE) && (reboot_mode != ADB_REBOOT_MODE))
   boot_into_recovery=1;
  dprintf(0, "[charger] %s() custom_power_on_charger()=%x check_reboot_mode()=%0x\n", __func__, custom_power_on_charger(), reboot_mode);
 }
 #endif
 
 if (reboot_mode == RECOVERY_MODE) {
  boot_into_recovery = 1;
 } else if(reboot_mode == FASTBOOT_MODE) {
  goto fastboot;
 }

 那么熟悉这套机制,我们就可以添加自己的模式了,比如闹钟模式,工厂模式等等;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息