Linux Suspend主要有以下三步:
1) 冻结用户态进程和内核态任务
2) 调用注册的设备的suspend的回调函数,顺序是按照注册顺序
3) 休眠核心设备和使CPU进入休眠态。
冻结进程(suspend_freeze_processes)是内核把进程列表中所有的进程的状态都设置为停止,并且保存所有进程的上下文。 当这些进程被解冻(suspend_thaw_processes)的时候,它们是不知道自己被冻结过的,只是简单的继续执行。可以通过读写sys文件/sys /power/state 是实现控制系统进入休眠,比如:
# echo standby > /sys/power/state
一、state_store()
二、pm_suspend()
三、enter_state()
1.sys_sync()
同步文件系统。
2.suspend_prepare()
suspend前的准备工作。
2.1 pm_prepare_console()
给suspend分配一个虚拟终端来输出信息。
2.2 pm_notifier_call_chain(PM_SUSPEND_PREPARE)
广播一个系统要进入suspend的Notify,外设在收到通知时会做一些准备。
2.3 suspend_freeze_processes()
冻结所有的进程,这里将保存所有进程当前的状态,也许有一些进程会拒绝进入冻结状态,当有这样的进程存在的时候,会导 致冻结失败,此函数就会放弃冻结进程,并且解冻刚才冻结的所有进程。如果成功则返回,否则执行后续的恢复操作
2.4如果2.2或2.3中失败,即不可以suspend,则做一些恢复工作
2.4.1 pm_notifier_call_chain(PM_POST_SUSPEND)
广播一个系统suspend结束的Notify,外设在收到通知时会做一些准备。
2.4.2pm_restore_console()
恢复控制台。
3.suspend_devices_and_enter()
3.1 suspend_console()
Suspend console子系统,即printk将不能打印了。
3.2 dpm_suspend_start()
Suspend所有非系统设备,即调用所有注册设备的suspend回调函数。
3.2.1 dpm_prepare()
调用设备的prepare()函数。
3.2.2dpm_suspend()
调用设备的suspend()函数。
3.3 suspend_enter()
使系统进入要求的sleep状态,然后停在这儿,只有当系统被中断或者其他事件唤醒时,此函数才返回。
3.3.1 suspend_ops->prepare()
CPU休眠的prepare()函数。
3.3.2 dpm_suspend_end()
调用设备的suspend_late()函数。
①dpm_suspend_late()
执行设备的suspend_late函数。
②dpm_suspend_noirq()
执行设备的suspend_noirq。
3.3.3 suspend_ops->prepare_late()
CPU休眠的prepare_late()函数。
3.3.4 disable_nonboot_cpus()
关闭非启动CPU。
3.3.5 arch_suspend_disable_irqs()
关闭所有非唤醒源的中断。
3.3.6 syscore_suspend()
系统核心设备休眠。
3.3.7 pm_wakeup_pending()
在write wakeup_count到调用pm_wakeup_pending这一段时间内,wakeup events framework会照常产生wakeup events,因此如果pending返回true,则不能“enter”,终止suspend吧。
3.3.8 suspend_ops->enter()
处理器的休眠进入函数,休眠流程运行至此,等唤醒源上报唤醒事件后再往后执行唤醒流程。
3.3.9 syscore_resume()
唤醒系统核心设备。
3.3.10 arch_suspend_enable_irqs()
使能中断。
3.3.11 enable_nonboot_cpus()
使能非启动CPU。
3.3.12 suspend_ops->wake()
执行处理器的wake()函数。
3.3.13 dpm_resume_start()
唤醒外设。
①dpm_resume_noirq()
执行设备的resume_noirq()函数。
②dpm_resume_early()
执行设备的resume_early()函数。
3.3.14 suspend_ops->finish()
执行处理器的的finish()函数。
3.4dpm_resume_end()
resume所有非系统设备,即执行所有注册设备的resume回调函数。
3.4.1 dpm_resume()
调用函数的resume()函数
3.4.2dpm_complete()
调用外设的complete()函数
3.5 resume_console()
resume console子系统,即printk可用了。
3.6 suspend_ops->end()
4. suspend_finish()
4.1 suspend_thaw_processes()
解冻进程。
4.2pm_notifier_call_chain(PM_POST_SUSPEND)
广播一个系统suspend结束的Notify,外设在收到通知时会做一些准备。
4.3pm_restore_console()
恢复控制台。