Linux内核睡眠唤醒流程

2023年 2月 19日 91点热度 0人点赞 0条评论

在用户空间向文件/sys/power/state写入mem即可触发Linux内核睡眠(Suspend)功能。

相关功能代码见:kernel/power/main.c和suspend.c等文件。

Linux内核Suspend总体流程如下:

state_store()->
    pm_suspend()->
        pm_suspend_marker("entry")      ## 1、标记进入睡眠
        enter_state()->                 ## 2、处理睡眠相关工作,重点关注
            sys_sync()                      ## 2.1、同步文件系统
            suspend_prepare()               ## 2.2、准备进入系统睡眠状态,并冻结用户空间进程和内核线程
            suspend_devices_and_enter()     ## 2.3、休眠外设并进入系统睡眠状态,该函数在系统唤醒时返回
            suspend_finish()                ## 2.4、睡眠结束并被唤醒
        pm_suspend_marker("exit")       ## 3、标记退出睡眠

下面重点介绍suspend_devices_and_enter()函数的流程:

suspend_devices_and_enter()->
    ## 1、冻结串口,可以在u-boot传入no_console_suspend,释放suspend流程中串口打印
    suspend_console()
    
    ## 2、外设驱动suspend
    dpm_suspend_start()->       
        dpm_prepare()->         
            device_prepare()    ## 执行设备电源管理函数中的prepare函数
        dpm_suspend()->
            device_suspend()->
                __device_suspend()->
                    dpm_run_callback()->
                        initcall_debug_start()  ## 显示调用的各suspend()函数名等信息,需要打开pm_print_times
                        cb()                    ## 执行各.suspend()函数,包括:外设驱动,电源域,总线等(重点关注****)
                        initcall_debug_report() ## 显示各suspend()函数返回值和执行时间
    
    ## 3、系统进入睡眠状态,该流程同时处理唤醒操作
    suspend_enter()->           
        platform_suspend_prepare()
        dpm_suspend_late(PMSG_SUSPEND)->
            device_suspend_late()->             
                __device_suspend_late()->
                    dpm_run_callback()->
                        initcall_debug_start()  ## 显示调用的各suspend()函数名等信息,需要打开pm_print_times
                        cb()                    ## 执行各.suspend_late()函数  (重点关注****)
                        initcall_debug_report() ## 显示各.suspend_late()函数返回值和执行时间
        
        dpm_suspend_noirq(PMSG_SUSPEND)->
            device_suspend_noirq()->
                __device_suspend_noirq()->
                    dpm_run_callback()->
                        initcall_debug_start()  ## 显示调用的各suspend()函数名等信息,需要打开pm_print_times
                        cb()                    ## 执行各.suspend_noirq()函数  (重点关注****)
                        initcall_debug_report() ## 显示各.suspend_noirq()函数返回值和执行时间                    
                    
        disable_nonboot_cpus()          ## 冻结非启动cpu
        arch_suspend_disable_irqs()     ## 关中断
        syscore_suspend()               ## 执行注册在syscore_ops_list上的syscore_ops的suspend

 ##################################### 开始唤醒,流程和suspend相反 #######################
        
        syscore_resume()
        arch_suspend_enable_irqs()
        enable_nonboot_cpus()
        
        dpm_resume_noirq(PMSG_RESUME)
        
        dpm_resume_early()
        platform_resume_finish()
        dpm_resume_end(PMSG_RESUME)
        resume_console()

注:本文基于RockPI 4A单板Debian系统Linux 4.4内核。

原文地址: Linux内核睡眠唤醒流程

本文来自:https://blog.duhbb.com

本文链接地址:Linux内核睡眠唤醒流程,英雄不问来路,转载请注明出处,谢谢。

有话想说:那就赶紧去给我留言吧。

rainbow

这个人很懒,什么都没留下

文章评论