从reboot命令开始

void reboot_main(void)
{int types[] = {RB_AUTOBOOT, RB_HALT_SYSTEM, RB_POWER_OFF},sigs[] = {SIGTERM, SIGUSR1, SIGUSR2}, idx;if (!(toys.optflags & FLAG_n)) sync();idx = stridx("hp", *toys.which->name)+1;if (toys.optflags & FLAG_f) toys.exitval = reboot(types[idx]);else toys.exitval = kill(1, sigs[idx]);
}

通过查看toybox中reboot命令的实现,如果存在-f选项,那么会不发送信号到init,而是直接reboot,如果不存在-f选项,那么会发送信号给init,后续关机流程由init接管。之所以要交给init处理,是为了让init对上层app进行通知处理,从而在关机前能够保存用户数据。

toys.exitval = kill(1, sigs[idx]);

这一条指令就是发送signal到进程号为1的进程,也就是我们常说的init进程。可以看到不同的reboot type,对应着不同的signale type:

RB_AUTOBOOT --- SIGTERM
RB_HALT_SYSTEM --- SIGUSR1
RB_POWER_OFF --- SIGUSR2

我们先跟一下reboot这一条线:

#include <unistd.h>
#include <sys/reboot.h>extern "C" int __reboot(int, int, int, void*);int reboot(int mode) {return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, mode, NULL);
}

对于arm64平台它的进一步底层实现为一个系统调用bionic/libc/arch-arm64/syscalls/__reboot.S:

#include <private/bionic_asm.h>ENTRY(__reboot)mov     x8, __NR_rebootsvc     #0cmn     x0, #(MAX_ERRNO + 1)cneg    x0, x0, hib.hi    __set_errno_internalret
END(__reboot)
.hidden __reboot

svc会触发系统调用进入内核执行对应的系统调用。对应于magic值的定义都是统一的:

#define LINUX_REBOOT_MAGIC1 0xfee1dead
#define LINUX_REBOOT_MAGIC2 672274793

对于另外一条线,发送信号给init进程,那么后续的动作全部都会交由init进程去处理了,init进程处理和上面的方式不同的地方就是会进行一些关机前的操作,并且最终同样使用reboot系统调用触发重启或者关机。

static void set_default(void)
{sigset_t signal_set_c;sigatexit(SIG_DFL);sigfillset(&signal_set_c);sigprocmask(SIG_UNBLOCK,&signal_set_c, NULL);run_action_from_list(SHUTDOWN);error_msg("The system is going down NOW!");kill(-1, SIGTERM);error_msg("Sent SIGTERM to all processes");sync();sleep(1);kill(-1,SIGKILL);sync();
}static void halt_poweroff_reboot_handler(int sig_no)
{unsigned int reboot_magic_no = 0;pid_t pid;set_default();switch (sig_no) {case SIGUSR1:error_msg("Requesting system halt");reboot_magic_no=RB_HALT_SYSTEM;break;case SIGUSR2:error_msg("Requesting system poweroff");reboot_magic_no=RB_POWER_OFF;break;case SIGTERM:error_msg("Requesting system reboot");reboot_magic_no=RB_AUTOBOOT;break;default:break;}sleep(1);pid = vfork();if (pid == 0) {reboot(reboot_magic_no);_exit(EXIT_SUCCESS);}while(1) sleep(1);
}

init进程处理关机的流程是:

  1. 先运行shutdown action list注销系统服务
  2. 运行kill(-1, SIGTERM);发送SIGTERM给系统中除了init外的所有进程
  3. 运行kill(-1,SIGKILL);发送SIGKILL给系统中除了init外的所有进程

Android平台的实现

做过高通项目的同学会发现高通自己实现了reboot的命令程序,而没有使用toybox。

#define ANDROID_RB_PROPERTY "sys.powerctl"ret = property_set(ANDROID_RB_PROPERTY, property_val);if (ret < 0) {perror(cmd);exit(EXIT_FAILURE);}

reboot命令最终是通过设置一个android property来做此操作的,该property是sys.powerctl。那么设置此property之后系统会执行些什么呢?实际上在init进程中会监控此property并触发对应的操作。它的函数调用栈为:

property_changed -> on property sys.powerctl -> HandlePowerctlMessage ${sys.powerctl}

其init实现的内容和上面介绍的Linux系统的实现也大同小异,这里就不做赘述了

Linux上层关机和reboot流程相关推荐

  1. Android 关机(reboot)流程 -- sys.powerctl

    Base On Android 4.2 recovery 和 reboot流程 part 1. reboot recovery流程. 1,RecoverySystem.java中     privat ...

  2. linux 关机 待机,Linux正确关机shutdown、reboot、halt、poweroff

    Linux和windows不一样,windows是单用户."假多任务"的操作系统,而Linux是名副其实的多用户多任务的,假设你和别人同时使用一台服务器,你的任务完成了,但是别人的 ...

  3. android 关机 流程_Android系统关机的全流程解析

    在PowerManager的API文档中,给出了一个关机/重启接口: public void reboot (String reason) 对于这个接口的描述很简单,就是几句话. 接口的作用就是重启设 ...

  4. Linux系统捕获数据包流程

    Linux系统捕获数据包流程 为了提高数据包的捕获效率,瓶颈问题是一个需要非常关注的焦点.减少在捕获数据包过程中的瓶颈,就能够提高数据包捕获的整体性能.下面本文将以Linux操作系统为平台,分析捕获数 ...

  5. Linux的关机命令和重启命令

    Linux的关机命令和重启命令 文章目录: 1 关机命令 2 重启命令 : 1 关机命令 1.halt :立刻关机(一般加-p 关闭电源) 2.poweroff: 立刻关机 3.shutdown -h ...

  6. Linux下关机、重启

    Linux下重启: reboot                   #重启 shutdown -r now   #计算机会立刻重启 Linux下关机: halt #关机 shutdown -h no ...

  7. Linux命令关机/重启和Windows系统dos命令关机/重启

    Linux命令关机/重启: 关机 shutdown –h now shutdown –h 20:25 shutdown –h +10 halt 立马关机 系统会在今天20:25关机 十分钟后关机 关闭 ...

  8. linux关机方法有哪些?有何区别_Linux关机命令大全:Linux各关机命令之间的区别和用法...

    Linux怎么用命令来进行关机/重启呢?Linux是一套免费使用和自由传播的类Unix操作系统,想使用Linux系统的关机命令必须要拿到root权限,下面给大家介绍一些Linux常用的关机命令以及各关 ...

  9. Linux中关机与重启命令

    Linux中关机与重启命令 Linux中关机与重启命令 1. shutdown命令(较为安全,能正确保存服务) a) 格式:[root@localhost~]# shutdown [选项] 时间 b) ...

  10. linux的关机重启命令汇总

    1. 关机重启命令汇总 halt 关机 root用户 halt:只关闭系统,电源还在运行 halt -p:关闭系统,关闭电源(先执行halt,再执行poweroff) poweroff 关机 root ...

最新文章

  1. visual studio 多行编辑 列编辑
  2. Android实战】DroidPlugin插件化应用分析
  3. React Antd Upload自定义上传customRequest
  4. 2016年Web前端面试题
  5. 这也许是你不曾留意过的 Mybatis 细节
  6. lwip+freeRTOS 实现热插拔功能
  7. Oracle 摘去数据块的面纱
  8. Tomcat服务器安装PFX格式证书
  9. 一样入职的应届生工资不一样_为什么每月工资一样,但扣的个税不一样?
  10. 教你如何关闭Mac电脑的Microsoft AutoUpdate弹框提示
  11. android studio最新教程pdf下载,android studio教程pdf下
  12. 华为AC旁路二层组网隧道转发示例
  13. 面向服务与微服务架构
  14. VUE 项目中引入外部js文件(CND引入)
  15. 使用Charles不能抓取到Ios手机的数据包
  16. python 异常处理 库_python捕获数据库异常处理
  17. J.P. Morgan:AI for Investing(脱水解读)
  18. 概率论与数理统计练习
  19. 用计算机计算根号2 2-1,如何计算根号2?
  20. ANSYS_Q3D仿真激光发射的寄生电感

热门文章

  1. 200行代码实现N子棋(以五子棋为例)
  2. springboot-shiro-jwt-redis实现用户登录的认证与授权(前后端分离)需要有一定shiro、jwt、redis、springboot基础
  3. Nginx不停机升级
  4. 三国史诗——三国官制(一)
  5. 获取交换机和PC网卡接口对应关系
  6. 解决java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionV
  7. 问题记录:node.js连接数据库出现两个问题getaddrinfo ENOTFOUND locahost;Client does not support authentication protoco
  8. 函数图像的变换 与 解析式的变换 之关系
  9. java表白小程序_c语言表白小程序代码创意
  10. Error 4 opening dom ASM/Self in 0x8283c00