android重启流程 点击打开链接

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

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

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

public static void reboot(String reason) throws IOException
{
rebootNative(reason);
}

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

{ "rebootNative", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot },

static void android_os_Power_reboot(JNIEnv *env, jobject clazz, jstring reason)
{
sync();
#ifdef HAVE_ANDROID_OS
if (reason == NULL) {
reboot(RB_AUTOBOOT);
} else {
const char *chars = env->GetStringUTFChars(reason, NULL);
__reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
LINUX_REBOOT_CMD_RESTART2, (char*) chars);
env->ReleaseStringUTFChars(reason, chars); // In case it fails.
}
jniThrowIOException(env, errno);
#endif
}

重点关注__reboot这个函数,其带4个参数,具体函数定义是在内核里kernel/sys.c

SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
void __user *, arg)

{

.......

.......

/* For safety, we require "magic" arguments. */
if (magic1 != LINUX_REBOOT_MAGIC1 || //从这里可以看出其实magic1和magic2这两个参数其实没啥用,只是linux为了自身安全而带的两个参数
(magic2 != LINUX_REBOOT_MAGIC2 &&//重点在cmd这个参数
magic2 != LINUX_REBOOT_MAGIC2A &&
magic2 != LINUX_REBOOT_MAGIC2B &&
magic2 != LINUX_REBOOT_MAGIC2C))
return -EINVAL;

.......

.......

.......

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

case LINUX_REBOOT_CMD_HALT:
kernel_halt();
do_exit(0);
panic("cannot halt");

case LINUX_REBOOT_CMD_POWER_OFF:
kernel_power_off();
do_exit(0);
break;

case LINUX_REBOOT_CMD_RESTART2:
if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {
ret = -EFAULT;
break;
}
buffer[sizeof(buffer) - 1] = '\0';

kernel_restart(buffer);
break;

}

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

kernel/sys.c:

void kernel_restart(char *cmd)
{

......

......
machine_restart(cmd);
}

----->arch/arm/kernel/process.c:

void machine_restart(char *cmd)
{
arm_pm_restart(reboot_mode, cmd);
}

----->arch/arm/kernel/process.c:

void arm_machine_restart(char mode, const char *cmd)
{
......

......

arch_reset(mode, cmd);

/*
* Whoops - the architecture was unable to reboot.
* Tell the user!
*/
mdelay(1000);
printk("Reboot failed -- System halted\n");
while (1);
}

----->arch/arm/mach-mmp/reset.c:

void arch_reset(char mode, const char *cmd)
{
if (cpu_is_pxa910() || cpu_is_pxa168())
pxa_arch_reset(mode, cmd);
else
return;
}

----->arch/arm/mach-mmp/reset.c:

static void pxa_arch_reset(char mode, const char *cmd)
{
switch (mode) {
case 's':
/* Jump into ROM at address 0 */
cpu_reset(0);
break;
case 'w':
default:
do_wdt_reset(cmd);
break;
}
}

----->arch/arm/mach-mmp/reset.c:

static void do_wdt_reset(const char *cmd)
{

......

......

if (cpu_is_pxa910())
watchdog_virt_base = CP_TIMERS2_VIRT_BASE;
else if (cpu_is_pxa168())
watchdog_virt_base = TIMERS1_VIRT_BASE;
else
return;

/* reset/enable WDT clock */
writel(0x7, MPMU_WDTPCR);
readl(MPMU_WDTPCR);
writel(0x3, MPMU_WDTPCR);
readl(MPMU_WDTPCR);


if (cpu_is_pxa910()) {
if (cmd && !strcmp(cmd, "recovery")) {
for (i = 0, backup = 0; i < 4; i++) {
backup <<= 8;
backup |= *(cmd + i);
}
do {
writel(backup, REG_RTC_BR0);
} while (readl(REG_RTC_BR0) != backup);

.......

.......

.......

}

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

做不同的事情,比如这里

if (cmd && !strcmp(cmd, "recovery")) {
for (i = 0, backup = 0; i < 4; i++) {
backup <<= 8;
backup |= *(cmd + i);
}
如果传下来的字符串是recovery那么,就在RTC寄存器里设置某个特定值,当uboot里读取RTC寄存器的时候如果获取了这个

特定值,那就可以起recovery这个动作了,大致流程是这样,希望对大家有帮助,偶人比较懒不喜欢多写注释,有兴趣的可以

根据这个路径自己看代码理解

更多相关文章

  1. Android4.4 Activity启动流程
  2. android开机动画启动流程
  3. Android Phone拨出电话流程
  4. android animation中的参数interpolator详解
  5. android button light 流程分析(三) — framework
  6. android NDK/JNI-实例开发流程
  7. Android 深入理解 View 的绘制流程和机制
  8. Android 实现一个http 带参数登录
  9. Android LOG机制流程图

随机推荐

  1. Android(安卓)basic1
  2. Android平板获取唯一标识DeviceId
  3. Android(安卓)basic1
  4. Android(安卓)自带图标库 android.R.draw
  5. rock960 android box compiling!
  6. android对话框的使用
  7. Android(安卓)自带图标库 android.R.draw
  8. android 6 sdk/ndk下载地址
  9. android 跳转到应用通知设置界面(Android
  10. Android多媒体开发(5)————利用Android(