转载:http://blog.csdn.net/linux_devices_driver/article/details/17928663
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; }
那么熟悉这套机制,我们就可以添加自己的模式了,比如闹钟模式,工厂模式等等;