linux下的关机和重启流程对于一般的桌面应用和网络服务器来说并不重要,但是在用户自己定义的嵌入式系统内核中就有一定的研究意义,通过了解Linux 关机重启的流程,我们对它可以修改和自定义,甚至以此为基础开发出全新的功能来。

1.概述

在linux下的关机和重启可能由两种行为引发,一是通过用户编程,一是系统自己产生的消息。用户和系统进行交互的方式也有两个,一个是系统调用:sys_reboot,另一个就是apm或则acpi的设备文件,通过对其操作也可以使系统关机或者重启。

2.通过系统调用sys_reboot的重启

这个系统调用定义了一系列的MAGIC_NUMBER,在调用的开始部分首先检查MAGIC_NUMBER是否正确,只有正确才继续向下运行。在重启的时候转向分支

case LINUX_REBOOT_CMD_RESTART:

首先使用notifier_call_chain向其它部分发出重启的消息,然后调用machine_restart函数完成重启。

machine_restart函数的开始部分有一段SMP相关的代码,主要完成多CPU时由一个CPU完成重启操作,其它CPU处于等待状态。之后系统根据一个变量reboot_thru_bios的内容判断重启方式,通过阅读reboot_setup我们可以得知,这个参数的内容是在系统启动时指定的,决定了是否利用bios,事实上是系统复位后的入口(FFFF:0000)地址的程序进行重启。在不通过bios进行重启的情况下,系统首先设定了重启标志,然后向端口0xfe写入数字0x64,这种重启的具体原理我还不大清楚,似乎是模拟了一次reset键的按下,希望大家和我讨论。在通过bios重启的情况下,系统同样先设定了重启模式,然后切换到了实模式,通过一条ljmp $0xffff,$0x0完成了重启。

3.通过系统调用sys_reboot进行关机

在系统调用的处理分支上,我们可以看到,首先同样是检查MAGIC_NUMBER,然后在

case LINUX_REBOOT_CMD_POWER_OFF:

的执行流程里面,又是使用notifier_call_chain发出了关闭计算机电源的消息,紧接着执行了machine_power_off函数。我们在machine_power_off函数中可以看到,如果pm_power_off这个函数指针不为空,那么系统就会通过调用这个函数进行关机。在apm已经加载的情况下(SMP除外),实际上pm_power_off函数实际上指向了apm.c中的apm_power_off,在这个函数里系统通过apm_info结构里的值,使用切换到实模式关机,或者使用apm_bios_call_simple函数调用保护模式下的apm接口关机两种方法。

4.apm驱动本身的关机过程

apm使用其注册的设备的ioctl接口完成apm的操作,在apm.c的do_ioctl函数中可以看见处理的分支。这里只有suspend和standby的代码,所以我们不能通过ioctl这种方法使用apm关机。

当用户按下POWER开关的时候,如果有apm模块,那么关机流程是由apm来处理的。apm驱动在初始化的时候启动了一个apm内核线程:apm_mainloop,系统会在这里检测到POWEROFF按键消息并且将其命名为APM_SYS_SUSPEND,以区别apm -s设置的APM_USER_SUSPEND模式。紧接着进入了apm_event_handler函数,又从apm_event_handler函数进入了check_events函数,处理函数对应的case分支上。系统同样使用了suspend函数进行关机,不过由于其它参数的原因,suspend最后调用的是关机的流程。

5.解决问题实例

1)按POWER键时某些主板死机

经查只有某些特定的驱动装载之后才会出现这样的情况,并且当使用关机系统调用sys_reboot的时候没有这样的问题。分析apm的处理流程,怀疑是在关机前驱动程序没有正确处理apm发出的询问消息造成的。由于部分驱动程序没有源代码,决定hack掉apm.c的关机部分,让两种方式的关机走同样的流程。于是把apm.c的check_events函数中对APM_SYS_SUSPEND部分改写为如下代码:

ret = exec_usermodehelper(poweroff_helper_path, argv, envp);

if (ret) {

printk(KERN_ERR

"apm.c: failed to exec %s , errno = %d\\n",

poweroff_helper_path, errno);

}

break;

For fast reboot support

static unsigned char fast_reboot_switch [] =

{

0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */

0x66, 0x25, 0x10, 0x11, 0x11, 0x11, /* andl $0x11111110,%eax */

0x66, 0x0f, 0x22, 0xc0, /* movl %eax,%cr0 */

0xea, 0x00, 0x00, 0x00, 0x70 /* ljmp $0x7000,$0x0000 */

};

系统就可以切换到实模式中,然后跳转到7000H:0位置开始执行。

6.ACPI概述

在2.4.20内核中ACPI模块被注明为试验和未完成,里面有一部分功能也许没有实现。如果APM和APCI两个模块同时编译进内核,APM在ACPI前被加载,APM起作用使ACPI退出。对于系统电量、电源实践一类的支持(主要是在笔记本上有用),靠的是acpid这个daemon程序。

没有一个功能类似apm的应用程序切换状态,acpi的程序仅仅完成了对acpi状态的查询。用户实现S0-S4的功能可以直接向/proc/acpi/sleep文件中写入数字来实现。通过读出(cat)其中的内容可以知道系统到底支持那些模式。

acpi模块的源代码主程序在linux/drivers/acpi/driver.c中,如果向sleep文件写东西,就转到了linux/drivers/acpi/ospm/system/sm_osl.c文件的sm_osl_proc_write_sleep函数中,这个函数后来调用了sm_osl_suspend函数。在这个函数里完成了各种功能,包括保护各种状态。最后真正的sleep是通过对acpi_enter_sleep_state的调用完成的,这个函数在linux/drivers/acpi/hardware/hwsleep.c文件中,这里写了acpi的寄存器使系统进入sleep状态。写寄存器的指令在这个目录下面的hwregs.c中。

7.总结

本文对acpi的介绍非常简略,实际上ACPI必定会成为将来linux内核中首选的电源管理方式。由于目前官方代码中ACPI版本较低,所以没有太详细的论述,希望将来的内核能有所改变。

linux意外重启分析,Linux关机重启流程分析相关推荐

  1. linux系统运行级别wq命令,Linux系统运行级别和关机重启命令介绍

    Linux系统运行级别介绍 Linux系统有七种运行级别(Run Level),各个运行级别下,系统有不同的状态,各个级别的意义描述如下. 0:关键级别 1:单用户运行级别,运行rc.sysinit和 ...

  2. Linux基础二(挂载、关机重启与系统等级)

    一.Linux 基础之挂载 1. 挂载和查询 1.1 挂载 什么叫挂载?装系统的时候要给硬盘分区,在 Windows 中要分 C 盘 D 盘 DEF 盘,这个操作我们叫做分配盘符,分配盘符之后我们就可 ...

  3. linux重置网络的命令,Linux常用网络命令和关机重启命令

    今天这篇文章有点特殊,为什么特殊呢,因为今天学到的一些网络命令在我这个Linux环境可能无法实践,有些人可能会说,环境有问题就去改啊,今天只能大概总结出来,无法像之前文章那样,给出实践的截图,而只是简 ...

  4. 05.Linux 常用命令-网络命令\关机重启命令

    网络命令 write\wall\ping\mail\last\lastlog\traceroute\netstat\setup\mount write wall ping ifconfig mail ...

  5. android开关机日志_(android 关机/重启)Android关机/重启流程解析

    --------------------------------Introduction-------------------------- 1. 在PowerManager的API文档中,给出了一个 ...

  6. 服务器无限关机重启,服务器反复关机重启

    服务器反复关机重启 内容精选 换一换 如果对弹性云服务器执行重启/关机操作,弹性云服务器长时间(大于30分钟)处于"正在重启"/"正在关机"状态时,建议执行强制 ...

  7. Framework原理分析之——Zygote进程流程分析

    在启动Zygote进程的分析中,我们知道其实是通过系统调用fork()函数来创建一个进程,然后执行Zygote.rc中的执行文件,从而开始Zygote进程业务. 本篇文章我们就来分析大名鼎鼎的Zygo ...

  8. 代码覆盖率原理分析:sys.settrace流程分析

    sys.settrace分析环境 本文环境python3.5.2 sys.settrace函数执行 首先我们继续查看示例代码如下: import sysdef trace(frame, event, ...

  9. VMP分析之VMP2.13流程分析(三)

    文章目录 VMP2.X版本特点 VMP2.13加壳 VMP2.13代码分析 进入VM虚拟机 保存堆栈 保存eflags和edx 保存ecx和edi 保存ebx 保存eax 保存ebx ebp和esi ...

  10. linux 内核协议栈 NAPI机制与处理流程分析(图解)

    目录 1 NAPI 机制 1.1 NAPI 缺陷 1.2 使用 NAPI 先决条件 1.3 非NAPI帧的接收 1.3.1 netif_rx - 将网卡中收到的数据包放到系统中的接收队列中 1.3.2 ...

最新文章

  1. Cocos2d之Texture2D类详解之将文件加载成Texture2D对象
  2. 攻防世界(pwn) level3
  3. 【笔记】An explainable deep machine vision framework for plant stress phenotyping
  4. XML原理及应用pdf
  5. Presenting the Permanent Generation
  6. MySQL 自带的四个数据库 介绍
  7. socket套接字TCP API
  8. c++之使用std::sort对坐标进行排序
  9. freenas 蜗牛星际_从“白群晖”到“蜗牛星际”,到底哪种NAS方案适合我?
  10. MATLAB图像去雾处理
  11. 数据结构1800题-错题集-第六章
  12. 快速搭建java后台管理系统
  13. ESP32 WS2812B灯带 代码
  14. 010项目沟通管理和干系人管理
  15. Matlab代码实现绘制趋势图
  16. 在VS2017中添加WTL窗口
  17. 【sklearn下的SVM转onnx】
  18. 车辆搜索 -使用triplet loss 训练车辆识别模型
  19. #990 Satisfiability of Equality Equations
  20. Linux用户空间和内核空间是什么?

热门文章

  1. ElasticSearch使用总结
  2. 使用Jekyll搭建博客
  3. Core Animation简介
  4. 来来来,个人blog第一弹——WordPress的Linux运行环境
  5. Activity的启动模式总结
  6. 盘点11个面向文档的开源NoSQL数据库
  7. 解决Windows平台通过cURL上传APP到蒲公英pgyer平台时无法使用中文升级描述的问题...
  8. Linux图形分区编辑器 GParted Live 1.0 Beta 发布
  9. 「THUPC2018」赛艇 / Citing
  10. Scala --- 第三章 数组相关操作