linux 关机和重启 机制

目录:

Linux 关机和重启机制

一.sys_reboot

二.apm capi

 

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

一.sys_reboot

linux下关机和重启命令主要有,shutdownreboothalt,poweroff,telinit,init。对于

poweroffreboothalt的符号链接,不过最终都调用reboot系统调用来完成关机和重启操作,该部分代码在kernel/sys.c中。

       在调用sys_reboot时,应该注意一点,

reboot doesn't sync: do that yourself before calling this.

所以在使用之前应该手动sync命令同步磁盘。

该函数流程如下,

i)                    检查调用者是否有合法调用reboot的权限。

ii)                  通过魔数magic1magic2,判断reboot系统调用是不是被偶然调用的。

iii)                对不同的调用使用情况区分,如

LINUX_REBOOT_CMD_RESTART, //restarting system

LINUX_REBOOT_CMD_HATL,  // system halted

LINUX_REBOOT_CMD_POWER_OFF //power down

LINUX_REBOOT_CMD_RESTART2 //接收命令字符 说明系统该如何关闭

LINUX_REBOOT_CMD_CAD_ON/OFF //用于决定是否允许Ctrl+alt+del组合键用于关闭并重启系统。

如果想禁止这个功能,可以在/etc/inittab文件的下面一行注释掉

Ca:12345:ctrlatldel:/sbin/shutdown –tl –a –r now

当然对于arm体系来说,用到的可能性较少

1.    restart

a) shutdown

       对于restart而言,首先需要通过blocking_notifier_call_chain这一通知机制,将挂在reboot_notifier_list上,对于reboot操作需要通知的设备进行消息通知。

       接着通知所有的驱动总线(包括i2c,usb,spi,platformbus),如果总线本身有shutdown操作,则先调用总线的shutdown操作,否则逐一调用总线上对应设备驱动的shutdown方法,接着清空sys文件系统(根据驱动模型思考,device_shutdown

       然后与上述描述类似的,进行shut down all system device,同样调用的是shutdown方法。

       最后调用machine_start,也就是arm_pm_restart,arm_machine_start进行重启操作。

b) arm_machine_start

       实际上最终调用的是arch_reset,对于不同的cpu,调用的arch_reset不同。

对于x86而言,开始部分有一段SMP相关的代码,主要完成多CPU时,一个CPU完成重启,而其他CPU处于等待的状态。之后根据变量reboot_thru_bios的内容判断重启方式,这个参数是reboot_setup指定的。在通过bios重启的情况下,系统同样先设定重启模式,然后切换到实模式,通过ljmp $0xffff,$0x0完成重启。

       对于arm mx25而言,相对简单,arch_reset最后调用mxc_wd_reset函数,该函数中,通过使能wacht dog时钟,使能Wdog,并且设置watch dog ctrl regSRS位,即software reset signal ,让WDOG 产生一个reset signal,从而实现reset操作。(而接下来的就是arm启动流程)

2.power_off

Power_off准备操作与resetart类似,shutdown结束后,最后调用的pm_board_off,

该方法可以在板级初始化的时候进行指定。

      a) arm

machine_power_off中,如果定义了pm_board_off 方法则会调用该函数关机,根

据体系不同设置,操作一般为拉低口线之类的操作。

      b) apm x86

而如果在apm已经加载的情况下(在arm中没有,x86中实现),实际指向的是

apm_power_off,在该函数里系统通过apm_info结构里的值,使用切换到实模式关机,或者使用apm_bios_call_simple函数调用保护模式下的apm接口关机两种方法。

             

apm使用其注册的设备的ioctl接口完成apm的操作,在apm.cdo_ioctl函数中可以看见处理的分支。这里只有suspendstandby的代码,所以我们不能通过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最后调用的是关机的流程。

你可能感兴趣的:(电源管理设计)