美文网首页
Linux内核睡眠唤醒流程

Linux内核睡眠唤醒流程

作者: 小田BSP | 来源:发表于2021-06-20 22:42 被阅读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://www.haomeiwen.com/subject/qxkeyltx.html