Linux 关机重启流程分析( 二 )




ret = exec_usermodehelper(poweroff_helper_path, argv, envp);
if (ret) {
printk(KERN_ERR
"apm.c: failed to exec %s , errno = %dn",
poweroff_helper_path, errno);
}
break;

For fast reboot support
static unsigned char fast_reboot_switch [] =
{
0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,陎 */
0x66, 0x25, 0x10, 0x11, 0x11, 0x11, /* andl $0x11111110,陎 */
0x66, 0x0f, 0x22, 0xc0, /* movl 陎,%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-2.4.20源代码


关于作者

范晓炬,联想(北京)有限公司软件设计中心嵌入式研发处开发工程师,研究兴趣为Linux内核,网络安全,XWindow系统,Linux桌面应用,人工智能系统 。你可以通过xiaoju_f@263.net联系他 。

推荐阅读