android 系统重启关机流程分析

android 系统重启关机流程分析 
分类: kernel 2012-07-20 17:27 981人阅读 评论(0) 收藏 举报 
1.5 android 系统重启关机流程分析


1.5.1 c语言中调用 reboot 函数


bionic/libc/unistd/reboot.c:33:


int reboot (int mode)


{


return __reboot( LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, mode,NULL );


}


1.5.2 通过 adb 让系统重启


adb reboot recovery 进入 recovery 模式


adb reboot bootloader 进入 fastboot 模式


adb reboot-bootloader


adb reboot 不带参数 系统正常重启


adb 是pc端工具,adbd是服务端,运行在手机


adbd 读取 socket 解析由 adb 传过来的命令串


int service_to_fd(const char *name)


if(!strncmp(name, "reboot:", 7)) {


void* arg = strdup(name + 7);


if(arg == 0) return -1;


ret = create_service_thread(reboot_service, arg);


system/core/adb/services.c:176:


void reboot_service(int fd, void *arg)


{


。。。


ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,


LINUX_REBOOT_CMD_RESTART2, (char *)arg);


。。。


}


bionic/libc/kernel/common/linux/reboot.h


#define LINUX_REBOOT_CMD_RESTART 0x01234567


#define LINUX_REBOOT_CMD_HALT 0xCDEF0123


kernel/include/linux/reboot.h:33:


#define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4


arg 对应字符串: recovery bootloader


./kernel/arch/arm/mach-msm/pm2.c


system/core/adb/commandline.c


if (!strcmp(argv[0], "reboot-bootloader"))


snprintf(command, sizeof(command), "reboot:bootloader");


如果输入 adb reboot-bootloader adb 会对该命令进行转换 相当于执行 adb rebootbootloader


1.5.3 fastboot 模式下系统重启


fastboot reboot 系统正常重启


fastboot reboot-bootloader 重启进入fastboot 模式


fastboot 是 appboot 提供的功能,可以用它来烧写 system 等镜像文件


bootable/bootloader/lk/app/aboot/aboot.c


APP_START(aboot)


.init = aboot_init,


void aboot_init(const struct app_descriptor *app)





。。。


fastboot_register("reboot", cmd_reboot);


fastboot_register("reboot-bootloader",cmd_reboot_bootloader);


。。。





void cmd_reboot(const char *arg, void *data, unsigned sz)


{


dprintf(INFO, "rebooting the device\n");


fastboot_okay("");


reboot_device(0);


}


void cmd_reboot_bootloader(const char *arg, void *data, unsignedsz)


{


dprintf(INFO, "rebooting the device\n");


fastboot_okay("");


reboot_device(FASTBOOT_MODE);


}


bootable/bootloader/lk/target/msm7630_surf/init.c:311:


void reboot_device(unsigned reboot_reason)


bootable/bootloader/lk/target/msm7627_ffa/init.c:174:


void reboot_device(unsigned reboot_reason)


void reboot_device(unsigned reboot_reason)


{


reboot(reboot_reason);


}


调用的是c函数:


bionic/libc/unistd/reboot.c:33:


int reboot (int mode)


{


return __reboot( LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, mode,NULL );


}


bootable/bootloader/lk/app/aboot/aboot.c:59:


#define FASTBOOT_MODE 0x77665500


if (!strcmp(cmd, "bootloader")) {


restart_reason = 0x77665500;


}


1.5.4 系统关机


正常按键关机


./frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindowManager.java


void showGlobalActionsDialog()


mGlobalActions.showDialog(keyguardShowing,isDeviceProvisioned());


调用文件:


./frameworks/policies/base/phone/com/android/internal/policy/impl/GlobalActions.java


中的函数:


public void showDialog(boolean keyguardShowing, booleanisDeviceProvisioned)


mDialog = createDialog();


调用本文件中的函数:


private AlertDialog createDialog()


public void onPress() {


ShutdownThread.shutdownAfterDisablingRadio(mContext, true);


}


调用文件:


./frameworks/policies/base/phone/com/android/internal/policy/impl/ShutdownThread.java


中的函数:


public static void shutdownAfterDisablingRadio(final Contextcontext, boolean confirm)


beginShutdownSequence(context)


调用本文件中的函数:


private static void beginShutdownSequence(Context context)


sInstance.start()


进入关机线程的run函数:


public void run() {


首先关蓝牙,关射频,然后再关电源


...


sBluetooth.disable(false)


...


sPhone.setRadio(false)


...


SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC);


...


Power.shutdown()


}


frameworks/base/core/java/android/os/Power.java:92:


public static native void shutdown();


frameworks/base/core/jni/android_os_Power.cpp:107:


{ "shutdown", "()V", (void*)android_os_Power_shutdown },


jni 调用


static void android_os_Power_shutdown(JNIEnv *env, jobjectclazz)


{


sync();


#ifdef HAVE_ANDROID_OS


reboot(RB_POWER_OFF);


#endif


}


因为有 bionic/libc/include/sys/reboot.h:42:


#define RB_POWER_OFF LINUX_REBOOT_CMD_POWER_OFF


所以实际相对执行


reboot(LINUX_REBOOT_CMD_POWER_OFF);


__reboot( LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,LINUX_REBOOT_CMD_POWER_OFF, NULL );


这里的 __reboot 是libc中的系统调用


bionic/libc/arch-x86/syscalls/__reboot.S


#include<sys/linux-syscalls.h>


.text


.type __reboot, #function


.globl __reboot


.align 4


.fnstart


__reboot:


.save {r4, r7}


stmfd sp!, {r4, r7}


ldr r7, =__NR_reboot


swi #0


ldmfd sp!, {r4, r7}


movs r0, r0


bxpl lr


b __set_syscall_errno


.fnend


1.5.5 内核中的系统调用 reboot


__NR_reboot 执行的是内核中的系统调用:


kernel/kernel/sys.c:310:


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


void __user *, arg)


{


char buffer[256];


int ret = 0;


if (!capable(CAP_SYS_BOOT))


return -EPERM;


if (magic1 != LINUX_REBOOT_MAGIC1 ||


(magic2 != LINUX_REBOOT_MAGIC2&&


magic2 != LINUX_REBOOT_MAGIC2A&&


magic2 != LINUX_REBOOT_MAGIC2B&&


magic2 != LINUX_REBOOT_MAGIC2C))


return -EINVAL;


if ((cmd == LINUX_REBOOT_CMD_POWER_OFF)&& !pm_power_off)


cmd = LINUX_REBOOT_CMD_HALT;


lock_kernel();


switch (cmd) {


case LINUX_REBOOT_CMD_RESTART:


kernel_restart(NULL);


break;


case LINUX_REBOOT_CMD_CAD_ON:


C_A_D = 1;


break;


case LINUX_REBOOT_CMD_CAD_OFF:


C_A_D = 0;


break;


case LINUX_REBOOT_CMD_HALT:


kernel_halt();


unlock_kernel();


do_exit(0);


panic("cannot halt");


case LINUX_REBOOT_CMD_POWER_OFF:


kernel_power_off();


unlock_kernel();


do_exit(0);


break;


case LINUX_REBOOT_CMD_RESTART2:


if (strncpy_from_user(&buffer[0], arg,sizeof(buffer) - 1) < 0) {


unlock_kernel();


return -EFAULT;


}


buffer[sizeof(buffer) - 1] = '\0';


kernel_restart(buffer);


break;


#ifdef CONFIG_KEXEC


case LINUX_REBOOT_CMD_KEXEC:


ret = kernel_kexec();


break;


#endif


#ifdef CONFIG_HIBERNATION


case LINUX_REBOOT_CMD_SW_SUSPEND:


ret = hibernate();


break;


#endif


default:


ret = -EINVAL;


break;


}


unlock_kernel();


return ret;


}


void kernel_restart(char *cmd)


{


kernel_restart_prepare(cmd);


if (!cmd)


printk(KERN_EMERG "Restarting system.\n");


else


printk(KERN_EMERG "Restarting system with command '%s'.\n",cmd);


machine_restart(cmd);


}


kernel/kernel/sys.c:341:


void kernel_power_off(void)


{


kernel_shutdown_prepare(SYSTEM_POWER_OFF);


if (pm_power_off_prepare)


pm_power_off_prepare();


disable_nonboot_cpus();


sysdev_shutdown();


printk(KERN_EMERG "Power down.\n");


machine_power_off();


}


./kernel/arch/arm/kernel/process.c:219:


void machine_restart(char *cmd)


{


arm_pm_restart(reboot_mode, cmd);


}


void machine_power_off(void)


{


if (pm_power_off)


pm_power_off();


}


因为./kernel/arch/arm/mach-msm/pm2.c:1740:中有:


arm_pm_restart = msm_pm_restart;


pm_power_off = msm_pm_power_off;


所以 arm_pm_restart 调用的是:


static void msm_pm_restart(char str, const char *cmd)


{


msm_rpcrouter_close();


msm_proc_comm(PCOM_RESET_CHIP, &restart_reason,0);


for (;;)


;


}


pm_power_off 调用的是:


static void msm_pm_power_off(void)


{


msm_rpcrouter_close();


msm_proc_comm(PCOM_POWER_DOWN, 0, 0);


for (;;)


;


}


msm_proc_comm 是芯片级别的操作


msm_proc_comm_reset_modem_now 对modem芯片进行重启


kernel/arch/arm/mach-msm/proc_comm.c:98:


int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned*data2)


{


。。。


writel(cmd, base + APP_COMMAND);


writel(data1 ? *data1 : 0, base + APP_DATA1);


writel(data2 ? *data2 : 0, base + APP_DATA2);


。。。


}


内核里面writel是如何实现的


http://blog.chinaunix.net/u2/77776/showart_1404857.html


补充信息:


static int msm_reboot_call


(struct notifier_block *this, unsigned long code, void*_cmd)


{


if ((code == SYS_RESTART) &&_cmd) {


char *cmd = _cmd;


if (!strcmp(cmd, "bootloader")) {


restart_reason = 0x77665500;


} else if (!strcmp(cmd, "recovery")) {


restart_reason = 0x77665502;


} else if (!strcmp(cmd, "eraseflash")) {


restart_reason = 0x776655EF;


} else if (!strncmp(cmd, "oem-", 4)) {


unsigned code = simple_strtoul(cmd + 4, 0, 16) &0xff;


restart_reason = 0x6f656d00 | code;


} else {


restart_reason = 0x77665501;


}


}


return NOTIFY_DONE;


}


static struct notifier_block msm_reboot_notifier = {


.notifier_call = msm_reboot_call,


};


static int __init msm_pm_init(void)


register_reboot_notifier(&msm_reboot_notifier);


内核编译相关:


kernel/arch/arm/mach-msm/pm2.c:1701: restart_reason =0x77665500;


kernel/arch/arm/mach-msm/pm.c:696: restart_reason =0x77665500;


kernel/arch/arm/mach-msm/Makefile:84:


ifdef CONFIG_MSM_N_WAY_SMSM


obj-$(CONFIG_PM) += pm2.o


else


obj-$(CONFIG_PM) += pm.o


endif


kernel/arch/arm/configs/msm7630-perf_defconfig:256:CONFIG_MSM_N_WAY_SMSM=y


kernel/arch/arm/configs/msm7627-perf_defconfig:247:CONFIG_MSM_N_WAY_SMSM=y


make -C kernelO=../out/target/product/msm7627_ffa/obj/KERNEL_OBJ ARCH=armCROSS_COMPILE=arm-eabi- msm7627-perf_defconfig


out/target/product/msm7627_ffa/obj/KERNEL_OBJ/.config


CONFIG_MSM_N_WAY_SMSM=y






分享到: 上一篇:git笔记 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值