1.5 android 系统重启关机流程分析

1.5.1 c语言中调用 reboot 函数  HAL层中重启系统的方法

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

使用需要的头文件:#include <sys/reboot.h>

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

android 系统重启关机 方法 非常好的一篇文章相关推荐

  1. android 自动重启测试,检测Android系统重启并生成测试用例的方法与流程

    本发明涉及软件技术领域,特别是一种检测Android系统重启并生成测试用例的方法. 背景技术: 目前安卓智能设备的功能越来越多,例如安卓智能电视或安卓智能盒子等,而在不同功能间交叉操作有概率触发And ...

  2. android版本升级流程,基于Android系统的版本升级方法及其系统与流程

    本发明涉及通信技术领域,尤其涉及的是一种基于Android系统的版本升级方法及其系统. 背景技术: 随着移动互联网的普及,各种各样的App应运而生.慢慢的简单App的功能已经满足不了用户的需求,更多的 ...

  3. android系统添加关机铃声

    最近客户有个需求,要给设备加上开关机的铃声,网上搜了一下,开机铃声已经有解决办法,直接修改bootanimation实现,但是关机铃声却没有好的实现方法,于是决定自己来实现这个功能. 首先要确定实现这 ...

  4. android系统重启系统,安卓系统不停重启怎么办

    工具/原料 安卓手机 方法/步骤 1.就本人的经验来讲,手机自动重启的主要原因是系统问题,而内存卡导致系统出现问题的概率较大.虽然现在的智能手机可以将软件安装到内存卡上,然而如果内存卡质量有问题,可能 ...

  5. Android系统自定义关机充电图标

    需求描述 关机充电图标的修改地址在哪里?替换照片有哪些格式要求? 实现方案 图片路径: system/core/healthd/images/ 关机充电: system/core/healthd/he ...

  6. 系统架构设计方法-3-应用架构设计篇

    应用架构设计工作内容 工作内容-1-确定应用域 输入(架构资产部分) 输出模板和示例 工作内容-2-确定应用 输入(架构资产部分)  输出模板和示例 工作内容-3-确定应用模块 输入(架构资产部分) ...

  7. 系统架构设计方法-4-数据架构设计篇

    数据架构设计工作内容 数据分布:数据实体和应用的对应关系 个人感觉:这里面写数据流转不太妥,流传应该都是应用层面来完成的.应用和数据之间的读写关系的组合. 工作内容-1-确定数据域 系统架构设计模板和 ...

  8. 系统架构设计方法-5-技术架构设计篇

    技术架构设计工作内容 技术架构主要包括两大部分:软件-技术平台/组件.硬件-基础设施 主要是对应用和数据提供哪些可用资源 工作内容-1-分析平台组件的需求 输入(架构资产部分) 分析过程 输出模板和示 ...

  9. Android卡顿掉帧问题分析之原理篇

    当用户抱怨手机在使用过程中存在卡顿问题的时候,会严重影响用户对手机品牌的好感和应用APP的体验,从而导致用户对手机品牌的忠诚度降低或应用APP的装机留存率下降.所以无论是手机设备厂商还是应用APP开发 ...

最新文章

  1. LeetCode Reconstruct Original Digits from English
  2. 如何关闭360自定义错误页面
  3. Memcache分组和同步机制的实现
  4. Nginx源码分析 - Event事件篇 - Epoll事件模块(19)
  5. 《运维工程师成长之路》一2.2 小结
  6. 简单之美 | ZooKeeper应用案例
  7. win10进不去计算机配置,Win10电脑系统设置打不开的解决方法
  8. pdf关键字高亮 java_Java查找并高亮PDF文本过程解析
  9. 【plotly+ datashader+mapbox】Uber纽约上车点可视化/解决超大量地理数据可视化
  10. 网络安全攻击与防护--HTML学习
  11. 论文《Dialogue State Tracking with a Language Model using Schema-Driven Prompting》学习笔记
  12. 把牌分成两堆,让每堆面朝上的牌数目相同
  13. go 库 viper 配置解析神器
  14. 投稿Springer旗下Natural Hazard的时间记载
  15. 解决:Clipping input data to the valid range for imshow with RGB data
  16. 联网下载jar包导入本地Maven库
  17. 三、Unity2D游戏制作——角色制作
  18. 最新阿里P7技术体系:快来看看这些方案,你不懂还不学?
  19. 虚荣和骄傲会让你跌得很惨
  20. 【Activiti7】什么是工作流?

热门文章

  1. n阶换方c语言程序,求单偶阶与双偶阶幻方编程思想及其算法!
  2. 图片怎么等比缩放_mac图像缩放工具Teorex iResizer
  3. 最简单的matplotlib写法
  4. Spark Streaming(一)概述
  5. 经常被人忽视的:Pandas 文本数据处理!
  6. 一个参数一个Excel表,让你玩转Pandas中read_excel()表格读取!
  7. 肝!一文讲解JWT用户认证全过程
  8. python网络通信编程实例_python网络编程之数据传输UDP实例分析
  9. cocos2d-lua-win
  10. bootstrap学习(三)表单