Linux 关机重启流程分析

柳柳199789

柳柳199789

2016-01-29 19:46

Linux 关机重启流程分析,Linux 关机重启流程分析
  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)其中的内容
展开更多 50%)
分享

猜你喜欢

Linux 关机重启流程分析

Linux Linux命令 Linux安装 Linux编程 Linux桌面 Linux软件 Linux内核 Linux管理
Linux 关机重启流程分析

Linux命令之关机重启命令用法汇总

电脑入门
Linux命令之关机重启命令用法汇总

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

Windows XP 关机总是变成重启?

windows 操作系统
Windows XP 关机总是变成重启?

远程开关机、死机重启

电脑入门
远程开关机、死机重启

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

Linux关机命令详解

Linux Linux命令 Linux安装 Linux编程 Linux桌面 Linux软件 Linux内核 Linux管理
Linux关机命令详解

电脑关机后又自动重启动

电脑入门
电脑关机后又自动重启动

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

给你的FSO对象加把锁

给你的FSO对象加把锁

主流嵌入式Linux动态扩展技术比较分析

主流嵌入式Linux动态扩展技术比较分析
下拉加载更多内容 ↓