搜索
首页系统教程LINUX深入探讨Linux Kernel suspend/resume 过程的实现原理和相关技术

深入探讨Linux Kernel suspend/resume 过程的实现原理和相关技术

Feb 13, 2024 pm 03:45 PM
linuxlinux教程linux系统linux命令外壳脚本嵌入式linuxlinux入门linux学习

在Linux内核中,suspend/resume过程是一种非常重要的过程。它可以实现系统的休眠和唤醒,提高系统的能效和响应速度。在本文中,我们将深入探讨Linux Kernel suspend/resume 过程的实现原理和相关技术。

深入探讨Linux Kernel suspend/resume 过程的实现原理和相关技术

休眠/唤醒在嵌入式Linux中是非常重要的部分,嵌入式设备尽可能的进入休眠状 态来延长电池的续航时间.这篇文章就详细介绍一下Linux中休眠/唤醒是如何工作 的

参考文章:作者: zhangjiejing Date: 2010-04-07, http://www.thinksrc.com

我的linux内核版本:3.0.31

对于休眠(suspend)的简单介绍

在Linux中,休眠主要分三个主要的步骤:

1、冻结用户态进程和内核态任务

2、调用注册的设备的suspend的回调函数

3、顺序是按照注册顺序

休眠核心设备和使CPU进入休眠态冻结进程是内核把进程列表中所有的进程的状态都设置为停止,并且保存下所有进程的上下文. 当这些进程被解冻的时候,他们是不知道自己被冻结过的,只是简单的继续执行.如何让Linux进入休眠呢?用户可以通过读写sys文件/sys /power/state 是实现控制系统进入休眠. 比如

# echo mem > /sys/power/state

命令系统进入休眠. 也可以使用

# cat /sys/power/state

来得到内核支持哪几种休眠方式.

Linux Suspend 的流程

相关的文件:

你可以通过访问Linux内核网站来得到源代码,下面是文件的路径:

kernel/kernel/power/main.c

kernel/kernel/power/suspend.c

kernel/driver/base/power/main.c

接下来让我们详细的看一下Linux是怎么休眠/唤醒的. Let ‘s going to see how these happens.

用户对于/sys/power/state 的读写会调用到 main.c中的state_store(), 用户可以写入 const char * const pm_state[] 中定义的字符串, 比如”mem”, “standby”.当然一般是由suspend和resume的按键控制的

然后state_store()会调用enter_state(), 它首先会检查一些状态参数,然后同步文件系统. 下面是代码:

1. /** 
2.  \* enter_state - Do common work of entering low-power state. 
3.  \* @state:   pm_state structure for state we're entering. 
4.  \* 
5.  \* Make sure we're the only ones trying to enter a sleep state. Fail 
6.  \* if someone has beat us to it, since we don't want anything weird to 
7.  \* happen when we wake up. 
8.  \* Then, do the setup for suspend, enter the state, and cleaup (after 
9.  \* we've woken up). 
10.  */ 
11. int enter_state(suspend_state_t state) 
12. { 
13.   int error; 
14.  
15.   if (!valid_state(state)) 
16. ​    return -ENODEV; 
17.  
18.   if (!mutex_trylock(&pm_mutex)) 
19. ​    return -EBUSY; 
20.  
21.   printk(KERN_INFO "PM: Syncing filesystems ... "); 
22.   sys_sync(); 
23.   printk("done.\n"); 
24.  
25.   pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); 
26.   error = suspend_prepare(); 
27.   if (error) 
28. ​    goto Unlock; 
29.  
30.   if (suspend_test(TEST_FREEZER)) 
31. ​    goto Finish; 
32.  
33.   pr_debug("PM: Entering %s sleep\n", pm_states[state]); 
34.   pm_restrict_gfp_mask(); 
35.   error = suspend_devices_and_enter(state); 
36.   pm_restore_gfp_mask(); 
37.  
38.  Finish: 
39.   pr_debug("PM: Finishing wakeup.\n"); 
40.   suspend_finish(); 
41.  Unlock: 
42.   mutex_unlock(&pm_mutex); 
43.   return error; 
44. } 

 

准备, 冻结进程

当进入到suspend_prepare()中以后, 它会给suspend分配一个虚拟终端来输出信 息, 然后广播一个系统要进入suspend的Notify, 关闭掉用户态的helper进程, 然后依次调用suspend_freeze_processes()冻结所有的进程, 这里会保存所有进程当前的状态, 也许有一些进程会拒绝进入冻结状态, 当有这样的进程存在的时候, 会导致冻结失败,此函数就会放弃冻结进程,并且解冻刚才冻结的所有进程.

1. /** 
2.  \* suspend_prepare - Do prep work before entering low-power state. 
3.  \* 
4.  \* This is common code that is called for each state that we're entering. 
5.  \* Run suspend notifiers, allocate a console and stop all processes. 
6.  */ 
7. static int suspend_prepare(void) 
8. { 
9.   int error; 
10.  
11.   if (!suspend_ops || !suspend_ops-**>**enter) 
12. ​    return -EPERM; 
13.  
14.   pm_prepare_console(); 
15.  
16.   error = pm_notifier_call_chain(PM_SUSPEND_PREPARE); 
17.   if (error) 
18. ​    goto Finish; 
19.  
20.   error = usermodehelper_disable(); 
21.   if (error) 
22. ​    goto Finish; 
23.  
24.   error = suspend_freeze_processes(); 
25.   if (!error) 
26. ​    return 0; 
27.  
28.   suspend_thaw_processes(); 
29.   usermodehelper_enable(); 
30.  Finish: 
31.   pm_notifier_call_chain(PM_POST_SUSPEND); 
32.   pm_restore_console(); 
33.   return error; 
34. } 

让外设进入休眠

现在, 所有的进程(也包括workqueue/kthread) 都已经停止了, 内核态人物有 可能在停止的时候握有一些信号量, 所以如果这时候在外设里面去解锁这个信号 量有可能会发生死锁, 所以在外设的suspend()函数里面作lock/unlock锁要非常 小心,这里建议设计的时候就不要在suspend()里面等待锁. 而且因为suspend的时候,有一些Log是无法输出的,所以一旦出现问题,非常难调试.

然后kernel在这里会尝试释放一些内存.

最后会调用suspend_devices_and_enter()来把所有的外设休眠, 在这个函数中, 如果平台注册了suspend_pos(通常是在板级定义中定义和注册), 这里就会调用 suspend_ops->begin(), 然后driver/base/power/main.c 中的 device_suspend()->dpm_suspend() 会被调用,他们会依次调用驱动的suspend() 回调来休眠掉所有的设备.

当所有的设备休眠以后, suspend_ops->prepare()会被调用, 这个函数通常会作 一些准备工作来让板机进入休眠. 接下来Linux,在多核的CPU中的非启动CPU会被关掉, 通过注释看到是避免这些其他的CPU造成race condion,接下来的以后只有一个CPU在运行了.

suspend_ops 是板级的电源管理操作, 通常注册在文件 arch/xxx/mach-xxx/pm.c 中.

接下来, suspend_enter()会被调用, 这个函数会关闭arch irq, 调用 device_power_down(), 它会调用suspend_late()函数, 这个函数是系统真正进入 休眠最后调用的函数, 通常会在这个函数中作最后的检查. 如果检查没问题, 接 下来休眠所有的系统设备和总线, 并且调用 suspend_pos->enter() 来使CPU进入 省电状态. 这时候,就已经休眠了.代码的执行也就停在这里了

1. /** 
2.  \* suspend_devices_and_enter - suspend devices and enter the desired system 
3.  \*         sleep state. 
4.  \* @state:    state to enter 
5.  */ 
6. int suspend_devices_and_enter(suspend_state_t state) 
7. { 
8.   int error; 
9.  
10.   if (!suspend_ops) 
11. ​    return -ENOSYS; 
12.  
13.   trace_machine_suspend(state); 
14.   if (suspend_ops-**>**begin) { 
15. ​    error = suspend_ops-**>**begin(state); 
16. ​    if (error) 
17. ​      goto Close; 
18.   } 
19.   suspend_console(); 
20.   suspend_test_start(); 
21.   error = dpm_suspend_start(PMSG_SUSPEND); 
22.   if (error) { 
23. ​    printk(KERN_ERR "PM: Some devices failed to suspend\n"); 
24. ​    goto Recover_platform; 
25.   } 
26.   suspend_test_finish("suspend devices"); 
27.   if (suspend_test(TEST_DEVICES)) 
28. ​    goto Recover_platform; 
29.  
30.   error = suspend_enter(state); 
31.  
32.  Resume_devices: 
33.   suspend_test_start(); 
34.   dpm_resume_end(PMSG_RESUME); 
35.   suspend_test_finish("resume devices"); 
36.   resume_console(); 
37.  Close: 
38.   if (suspend_ops-**>**end) 
39. ​    suspend_ops-**>**end(); 
40.   trace_machine_suspend(PWR_EVENT_EXIT); 
41.   return error; 
42.  
43.  Recover_platform: 
44.   if (suspend_ops-**>**recover) 
45. ​    suspend_ops-**>**recover(); 
46.   goto Resume_devices; 
47. } 

RESUME

如果在休眠中系统被中断或者其他事件唤醒, 接下来的代码就会开始执行, 这个 唤醒的顺序是和休眠的循序相反的,所以系统设备和总线会首先唤醒,使能系统中 断, 使能休眠时候停止掉的非启动CPU, 以及调用suspend_ops->finish(), 而且 在suspend_devices_and_enter()函数中也会继续唤醒每个设备,使能虚拟终端, 最后调用 suspend_ops->end().

在返回到enter_state()函数中的, 当 suspend_devices_and_enter() 返回以后, 外设已经唤醒了, 但是进程和任务都还是冻结状态, 这里会调用suspend_finish()来解冻这些进程和任务, 而且发出Notify来表示系统已经从suspend状态退出, 唤醒终端.

到这里, 所有的休眠和唤醒就已经完毕了, 系统继续运行了.

总之,suspend/resume过程是Linux内核中不可或缺的一部分。它可以实现系统的休眠和唤醒,提高系统的能效和响应速度。希望本文能够帮助读者更好地理解Linux Kernel suspend/resume 过程的实现原理和相关技术。

以上是深入探讨Linux Kernel suspend/resume 过程的实现原理和相关技术的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:良许Linux教程网。如有侵权,请联系admin@php.cn删除
Linux软件的未来:Flatpak和Snap会替换本机桌面应用程序吗?Linux软件的未来:Flatpak和Snap会替换本机桌面应用程序吗?Apr 25, 2025 am 09:10 AM

多年来,Linux软件分布依赖于DEB和RPM等本地格式,并深深地根深蒂固。 但是,Flatpak和Snap已经出现,有望成为应用程序包装的通用方法。 本文考试

Linux和Windows处理设备驱动程序的区别有什么区别?Linux和Windows处理设备驱动程序的区别有什么区别?Apr 25, 2025 am 12:13 AM

Linux和Windows在处理设备驱动程序上的差异主要体现在驱动管理的灵活性和开发环境上。1.Linux采用模块化设计,驱动可以动态加载和卸载,开发者需深入理解内核机制。2.Windows依赖微软生态,驱动需通过WDK开发并签名认证,开发相对复杂但保证了系统的稳定性和安全性。

比较和对比Linux和Windows的安全模型。比较和对比Linux和Windows的安全模型。Apr 24, 2025 am 12:03 AM

Linux和Windows的安全模型各有优势。Linux提供灵活性和可定制性,通过用户权限、文件系统权限和SELinux/AppArmor实现安全。Windows则注重用户友好性,依赖WindowsDefender、UAC、防火墙和BitLocker保障安全。

Linux和Windows之间的硬件兼容性有何不同?Linux和Windows之间的硬件兼容性有何不同?Apr 23, 2025 am 12:15 AM

Linux和Windows在硬件兼容性上不同:Windows有广泛的驱动程序支持,Linux依赖社区和厂商。解决Linux兼容性问题可通过手动编译驱动,如克隆RTL8188EU驱动仓库、编译和安装;Windows用户需管理驱动程序以优化性能。

Linux和Windows之间虚拟化支持有哪些差异?Linux和Windows之间虚拟化支持有哪些差异?Apr 22, 2025 pm 06:09 PM

Linux和Windows在虚拟化支持上的主要区别在于:1)Linux提供KVM和Xen,性能和灵活性突出,适合高定制环境;2)Windows通过Hyper-V支持虚拟化,界面友好,与Microsoft生态系统紧密集成,适合依赖Microsoft软件的企业。

Linux系统管理员的主要任务是什么?Linux系统管理员的主要任务是什么?Apr 19, 2025 am 12:23 AM

Linux系统管理员的主要任务包括系统监控与性能调优、用户管理、软件包管理、安全管理与备份、故障排查与解决、性能优化与最佳实践。1.使用top、htop等工具监控系统性能,并进行调优。2.通过useradd等命令管理用户账户和权限。3.利用apt、yum管理软件包,确保系统更新和安全。4.配置防火墙、监控日志、进行数据备份以确保系统安全。5.通过日志分析和工具使用进行故障排查和解决。6.优化内核参数和应用配置,遵循最佳实践提升系统性能和稳定性。

很难学习Linux吗?很难学习Linux吗?Apr 18, 2025 am 12:23 AM

学习Linux并不难。1.Linux是一个开源操作系统,基于Unix,广泛应用于服务器、嵌入式系统和个人电脑。2.理解文件系统和权限管理是关键,文件系统是层次化的,权限包括读、写和执行。3.包管理系统如apt和dnf使得软件管理方便。4.进程管理通过ps和top命令实现。5.从基本命令如mkdir、cd、touch和nano开始学习,再尝试高级用法如shell脚本和文本处理。6.常见错误如权限问题可以通过sudo和chmod解决。7.性能优化建议包括使用htop监控资源、清理不必要文件和使用sy

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具