Linux关机过程详解

上一篇 / 下一篇  2007-12-08 01:32:44 / 个人分类:软件开发

51Testing软件测试网n"c }c Q n Yjn

在正常情况下halt或者reboot会调用shutdown,shutdown又会调用init来关闭电脑或者重新启动,所谓的正常情况是run level不等于0或者6的时候。51Testing软件测试网?:g?s#L2j"_

7@VV#tw${ fW e0

/sbin/poweroff相当于halt -p51Testing软件测试网4R[,jrW V

当执行shutdown -h now时,调用init 0--》init.d/halt---->/sbin/halt

@HmPO B k3{4p5a0

# the content of /etc/rc.d/init.d/halt
t`!ep&|0# halt          This file is executed by init when it goes into runlevel

#               0 (halt) or runlevel 6 (reboot). It kills all processes,
#               unmounts file systems and then either halts or reboots.51Testing软件测试网I+L U$a^/{2|~

sIbe3y1vA0

poweroff将会使halt调用reboot(BMAGIC_POWEROFF)函数,定义于<sys/reboot.h>

cjYBJ&YOp:y0

,u? f`K1fi7[&^0下面是man手册的节选内容:
sZ#j(@p'S%b v0DEscrīptION of shutdown51Testing软件测试网:Y8o4@7d ^4X*D;~
       shutdown brings the system down in a secure way. All logged-in users are notified that the system is going down, and login(1) is51Testing软件测试网-x3ky X%zO5c
       blocked. It is possible to shut the system down immediately or after a specified delay. All processes are first notified that the51Testing软件测试网%Sx6xbJR(tw
       system is going down by the signal SIGTERM. This gives programs like vi(1) the time to save the file being edited, mail and news pro-
!@2zrkny[0       cessing programs a chance to exit cleanly, etc. shutdown does its job by signalling the init process, asking it to change the run-
\(E~4H!MP?0       level. Runlevel 0 is used to halt the system, runlevel 6 is used to reboot the system, and runlevel 1 is used to put to system into a
E9z5Vx"v(m F0       state where administrative tasks can be performed; this is the default if neither the -h or -r flag is given to shutdown.   To see51Testing软件测试网4M,L'RBl|@Z
       which actions are taken on halt or reboot see the appropriate entries for these runlevels in the file /etc/inittab.
xR4O D7f*}#EH7A4S0
jUGpJ0Init can only capture CTRL-ALT-DEL and start shutdown in console mode. If the system is running the X window System, the X server
w.~s GC"[5?6us*P0       processes all key strokes. Some X11 environments make it possible to capture CTRL-ALT-DEL, but what exactly is done with that event
%wX4lG0|@TA*O0       depends on that environment.51Testing软件测试网X6}YD5O9aym.o&j

-f^;Nj? K m0       Shutdown wasn’t designed to be run setuid. /etc/shutdown.allow is not used to find out who is executing shutdown, it ONLY checks who51Testing软件测试网(N @0y/U1|/_X4}
       is currently logged in on (one of the) console(s).51Testing软件测试网 a j2[/x2R
51Testing软件测试网uw-r-}'] S
DEscrīptION of halt and reboot
X%dWT+V9U0       Halt notes that the system is being brought down in the file /var/log/wtmp, and then either tells the kernel to halt, reboot or
1?;u^Z}9M]'eL6@`"b0       poweroff the system.51Testing软件测试网5w5\b^U

#{Z&K:P S]*i AU0       If halt or reboot is called when the system is not in runlevel 0 or 6, in other words when it’s running normally, shutdown will be51Testing软件测试网oV6zMQ&K
       invoked instead (with the -h or -r flag). For more info see the shutdown(8) manpage.
2O"]Zrg YM051Testing软件测试网q|mw9`
Under older sysvinit releases , reboot and halt should never be called directly. From release 2.74 on halt and reboot invoke shut-
Q C"M+fn [k0       down(8) if the system is not in runlevel 0 or 6. This means that if halt or reboot cannot find out the current runlevel (for example,51Testing软件测试网j%eP0F0^.pNf R9r0Y
       when /var/run/utmp hasn’t been initialized correctly) shutdown will be called, which might not be what you want. Use the -f flag if51Testing软件测试网~0|eC6g/^?{
       you want to do a hard halt or reboot.
H@ l fj6M(|@2U&^0============================================================51Testing软件测试网6I pH3Z0g*R
51Testing软件测试网%tb ] J I%C1OC#ZM$v2C

Linux关机命令详解

H0cA9k\5ef8r0在linux下一些常用的关机/重启命令有shutdown、halt、reboot、及init,它们都可以达到重启系统的目的,但每个命令的内部工作过程是不同的。

];~5Fh g0

srt_!GgM0[0   1.shutdown51Testing软件测试网2{"m U:z8@7D]^

+w:y"aP1wD j3[0shutdown命令安全地将系统关机。 有些用户会使用直接断掉电源的方式来关闭linux,这是十分危险的。因为linux与windows不同,其后台运行着许多进程,所以强制关机可能会导 致进程的数据丢失﹐使系统处于不稳定的状态﹐甚至在有的系统中会损坏硬件设备。51Testing软件测试网H-^%S-i-EA.f

51Testing软件测试网!j.ax k*rERn

而在系统关机前使用shutdown命令﹐系统管理员会通知所有登录的用户系统将要关闭。并且login指令会被冻结﹐即新的用户不能再登录。直接 关机或者延迟一定的时间才关机都是可能的﹐还可能重启。这是由所有进程〔process〕都会收到系统所送达的信号〔signal〕决定的。这让像vi之 类的程序有时间储存目前正在编辑的文档﹐而像处理邮件〔mail〕和新闻〔news〕的程序则可以正常地离开等等。51Testing软件测试网1Q%gR1xo

gh6z:g Rnl0shutdown执行它的工作是送信号〔signal〕给init程序﹐要求它改变runlevel。Runlevel 0被用来停机〔halt〕﹐runlevel 6是用来重新激活〔reboot〕系统﹐而runlevel 1则是被用来让系统进入管理工作可以进行的状态﹔这是预设的﹐假定没有-h也没有-r参数给shutdown。要想了解在停机〔halt〕或者重新开机 〔reboot〕过程中做了哪些动作﹐你可以在这个文件/etc/inittab里看到这些runlevels相关的资料。51Testing软件测试网7f!G(HP ?L t&^

51Testing软件测试网W"fc.W7El,Id{

   shutdown 参数说明:51Testing软件测试网1AsGN@:r4n!O.c.}
[-t] 在改变到其它runlevel之前﹐告诉init多久以后关机。
p J&a%c6^%C0[-r] 重启计算器。
E5|?rY [ T6{u0[-k] 并不真正关机﹐只是送警告信号给每位登录者〔login〕。51Testing软件测试网/kx%r+i@/g,?
[-h] 关机后关闭电源〔halt〕。51Testing软件测试网d @KPzM~
[-n] 不用init﹐而是自己来关机。不鼓励使用这个选项﹐而且该选项所产生的后果往往不总是你所预期得到的。
WTl'\d5OY&@0[-c] cancel current process取消目前正在执行的关机程序。所以这个选项当然没有时间参数﹐但是可以输入一个用来解释的讯息﹐而这信息将会送到每位使用者。
I eVRM5uZ.w0[-f] 在重启计算器〔reboot〕时忽略fsck。51Testing软件测试网#M NGn0dQO
[-F] 在重启计算器〔reboot〕时强迫fsck。51Testing软件测试网4ildR:@
[-time] 设定关机〔shutdown〕前的时间。51Testing软件测试网C"fW+q2V ~

] aL N)K02.halt----最简单的关机命令51Testing软件测试网.V? P?r0O+A,Tm
其实halt就是调用shutdown -h。halt执行时﹐杀死应用进程﹐执行sync系统调用﹐文件系统写操作完成后就会停止内核。
Wv9^D'G,i0参数说明:
M"?1o `Z0[-n] 防止sync系统调用﹐它用在用fsck修补根分区之后﹐以阻止内核用老版本的超级块〔superblock〕覆盖修补过的超级块。51Testing软件测试网@8mP une
[-w] 并不是真正的重启或关机﹐只是写wtmp〔/var/log/wtmp〕纪录。
r.K6tqD"A%{ u0[-d] 不写wtmp纪录〔已包含在选项[-n]中〕。51Testing软件测试网8r\_ A @!K7r
[-f] 没有调用shutdown而强制关机或重启。
X]5BVGx0[-i] 关机〔或重启〕前﹐关掉所有的网络接口。
D1q.t{a,|V t0[-p] 该选项为缺省选项。就是关机时调用poweroff。
I QD-vD9e"b0
yf}xDDR+E O|03.reboot
R)If6j]0reboot的工作过程差不多跟halt一样﹐不过它是引发主机重启﹐而halt是关机。它的参数与halt相差不多。51Testing软件测试网x#I;I/o6A:W3h(Aj@

7k'V/Hq-WdzX04.init
,Y;h F*F3P{0init是所有进程的祖先﹐它的进程号始终为1﹐所以发送TERM信号给init会终止所有的用户进程﹑守护进程等。shutdown 就是使用这种机制。init定义了7个运行级别(runlevel),init 0为关机﹐init 1为重启。关于init可以长篇大论﹐这里就不再叙述。另外还有telinit命令可以改变init的运行级别﹐比如﹐telinit -iS可使系统进入单用户模式﹐并且得不到使用shutdown时的信息和等待时间。51Testing软件测试网5v f;S;s K {5K8G3i

51Testing软件测试网0ks$\mv3g3z p!^

===========================================================51Testing软件测试网7g$f @G o7~

Linux 关机重启流程分析

X+F!t ng3`)c#}m!}0范晓炬(xiaoju_f@263.net), 联想(北京)有限公司软件设计中心嵌入式研发处开发工程师, 联想(北京)有限公司软件设计中心51Testing软件测试网M"R#fs%_B+bt

Qls,[5`;F3O02003 年 8 月 11 日

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

} g[\R3E S/h01.概述51Testing软件测试网T H4Zrz A3f

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

]M|1P BQ3S-\0
wSNx.GW{0
51Testing软件测试网,oj6vb0T.v7^
51Testing软件测试网 DcB'A8{%T'i4G\ @
回页首
51Testing软件测试网R7O D?.s
51Testing软件测试网D#bgo/[P:Xqo r
51Testing软件测试网,v iV9KL

2.通过系统调用sys_reboot的重启51Testing软件测试网7Yy;S;h%yqR `4I~D

51Testing软件测试网b!Q:g'h4_F9yC#f?

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

oD V Zf5u0
case LINUX_REBOOT_CMD_RESTART:

R?A R"YP'v051Testing软件测试网z WUYO r

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

0UQ/I7jL I0

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

hJ/e.z-b0
V}t&v+C"G[B0
51Testing软件测试网plG4b!r*LT
51Testing软件测试网8K pUH5q N%~.C
回页首
51Testing软件测试网w3Y/M^$s7X@;k`

6{OH,[YZ0

1CTg7@ fk? y03.通过系统调用sys_reboot进行关机51Testing软件测试网z'g$b#?0bj

51Testing软件测试网8w Y5^R&V;h \

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

Q?u#oS$Zu%Op5HZE0
case LINUX_REBOOT_CMD_POWER_OFF:

:ic,Q:`hS-D051Testing软件测试网#Sw ~%F d3\

的执行流程里面,又是使用 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接口关机两种方法。

8om k"ETG/aX051Testing软件测试网 UQ0FGd8nR(Tv-@n D

i{6}a9Z8E2bUg$dY0
51Testing软件测试网CofyQA M!C\
回页首
51Testing软件测试网XTE]sJ%C+Q+`;Zd&d5{

a$Fu1UP051Testing软件测试网B q"|^!A@aX

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

zE{A8a051Testing软件测试网E!i3z$F_z

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

:Z%?8Yj!\!D8e3L0

G8ev N;\0当 用户按下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 最后调用的是关机的流程。

kOU;og)XN0
-g.C-R:x)P8y0
51Testing软件测试网]$z R$KJ}R

wH\:Z'Q0
回页首
51Testing软件测试网'P O}"p/R
51Testing软件测试网F;bDR&b!lc

nC |:gT05.解决问题实例

QjgbvJ"wI051Testing软件测试网.O]/V;m2X#Dh!G3f

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

z3Wd B'M4I(Xt0

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

"k#k}4Bj5D6in2O0
ret = exec_usermodehelper(poweroff_helper_path, argv, envp);51Testing软件测试网DP
Z}t+B
if (ret) {51Testing软件测试网n u@a5B'}u
printk(KERN_ERR
9^dj1X`d2}"@mN0"apm.c: failed to exec %s , errno = %d\\n",51Testing软件测试网l9L_D.P{
poweroff_helper_path, errno);
*FSr-M/Sl!Jq0}
ff%F@,g!oN0break;

]mdx'BN051Testing软件测试网&V`5L-l6E)J_.i

定义了一个用户态应用程序poweroff_helper_path,当POWEROFF键按下的时候系统运行这个kernel_helper程序。我们再写一个通过sys_reboot系统调用关机的程序,放在指定的位置下。死机的问题就解决了。

/p3e$|$M NX|051Testing软件测试网S0wP l1R4tly

2)快速返回实模式重启51Testing软件测试网(|L,k;z;d\_6Yy

]#w k] H0主要可以参考了process.c中的返回实模式的代码,比如我把real_mode_switch换成如下代码:

hp-c2V2CM,`Z:j\0
// For fast reboot support51Testing软件测试网fT&f4IBK
I2D	y p
static unsigned char fast_reboot_switch [] =
i-U;l(Utje.|!Y j9N0{
J EY`V\vp00x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */51Testing软件测试网g`e*N-[@}!q
0x66, 0x25, 0x10, 0x11, 0x11, 0x11, /* andl $0x11111110,%eax */
{p;a,MT.[` L^x }k00x66, 0x0f, 0x22, 0xc0, /* movl %eax,%cr0 */51Testing软件测试网2hG&es W
0xea, 0x00, 0x00, 0x00, 0x70 /* ljmp $0x7000,$0x0000 */51Testing软件测试网jW)WHM$p E_[.l
};

%L9YN f^@051Testing软件测试网$I6M2U2N6X

系统就可以切换到实模式中,然后跳转到7000H:0位置开始执行。51Testing软件测试网 F3tu$?%P@C

51Testing软件测试网-k/_a2o5P
51Testing软件测试网s*DK\/c K#]

7tS~2yILjX$Uj0
回页首

-l4?[/A8rNT_051Testing软件测试网Fh| TU7y F5S
51Testing软件测试网6pk1fgR%q,I

6.ACPI概述51Testing软件测试网9i|+u7o5n.N

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

3i};efD"iW051Testing软件测试网#Gf @\Isc

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

#Js(fxQ"{#O.I Z]0

1PD:FsFJ;L0acpi 模块的源代码主程序在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中。

mHjH~h*I0
6^6t.ZE w"s+s.H0

0Pr(o:C,J6u0
51Testing软件测试网%F8Z7T z owxMr5s
回页首
51Testing软件测试网/`3r$e)QA#N'De(P#i

~zA k:L8c0

)f lL~IxJ07.总结

Vt-C o:E`3J[3z6_^0

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

S9jg8p is"V$S0
6y gE5P+[Qctf{"w0
R-N]!^8zE7wi051Testing软件测试网#r[@Yb*V4??

参考资料51Testing软件测试网\vq yq zM3\*D

  • linux-2.4.20源代码
51Testing软件测试网(|[Vz_9Q g ya

关于作者

Qx/cH(J.@,EEk`0

du3c)R sY Sj(Lu0范晓炬,联想(北京)有限公司软件设计中心嵌入式研发处开发工程师,研究兴趣为 Linux 内核,网络安全,XWindow 系统,Linux 桌面应用,人工智能系统。你可以通过xiaoju_f@263.net联系他51Testing软件测试网&n5?4x)lJ#PN'c

========================================51Testing软件测试网KM$W| Q
51Testing软件测试网B Q*M.C,]-sd

E/Od XY051Testing软件测试网 h E3g#?hQ1W
参考资料:51Testing软件测试网"W b SGL ``
www.ibm.com/developerworks/cn/linux/embed/l-rb/index.html51Testing软件测试网ywu(mk X:D v
blog.chinaunix.net/u/7356/showart.php
p0`A9\P0if.ustc.edu.cn/~jbhuang/blog/archives/000265.html
5Q;xDnq[VB%z0www.ahinc.com/linux101/boot.htm

+f6^0q6f} WR,e:~0

TAG: 软件开发 Linux 关机过程

 

评分:0

我来说两句

Open Toolbar