Linux电源管理(6)_Generic PM之挂起功能

原文链接:Linux电源管理(6)_Generic PM之挂起功能

1.前言

Linux内核提供了三种暂停方式:Freeze,Standby和STR(暂停到RAM),在用户空间向” / sys / power / state”文件分别写入“ freeze”,“ standby”和“ mem”,可以触发。

另外内核中,挂起和恢复过程涉及到PM核心,设备PM,各个设备的驱动,平台相关的PM,CPU控制等多个模块,涉及控制台切换,进程冻结,CPU热插拔,唤醒处理等过个知识点。就让我们跟着内核代码,一一见识它们吧。

0

2.暂停功能有关的代码分布

内核中止功能相关的代码包括PM内核,设备PM,平台PM等几大块,具体如下:

1)PM核心

内核/电源/main.c----提供用户空间接口(/ sys /电源/状态)

kernel / power / suspend.c ----挂起功能的主逻辑

内核/电源/suspend_test.c----挂起功能的测试逻辑

内核/电源/控制台.c ----挂起过程中对控制台的处理逻辑

内核/电源/进程.c ----挂起过程中对进程的处理逻辑

2)平台相关的PM

include / linux / suspend.h ----定义平台相关的PM有关的操作函数集

arch / xxx / mach-xxx / xxx.c或者

arch / xxx / plat-xxx / xxx.c ----平台相关的电源管理操作

3.暂停和恢复过程概述

下面的图片对Linuxsuspend&resume过程由一个概述,读者可以顺着这个流程阅读内核源代码。具体的说明,可以参考后面的代码分析。

0

4.代码分析

4.1暂停入口

在用户空间执行如下操作:

回声“冻结”> / sys / power / state

回声“待机”> / sys / power / state

回声“内存”> / sys / power / state

会通过sysfs触发suspend的执行,相应的处理代码如下:

static ssize_t state_store(struct kobject *kobj,                           struct kobj_attribute *attr,                          const char *buf,                           size_t n){
  
      suspend_state_t state;    int error;    // 1. 获取自动睡眠锁    error = pm_autosleep_lock();    if (error)        return error;    // 2. 检查当前是否已处于非ON状态(禁止重复操作)    if (pm_autosleep_state() > PM_SUSPEND_ON) {
  
          error = -EBUSY;        goto out;    }    // 3. 解析输入状态并执行对应操作    state = decode_state(buf, n);    if (state < PM_SUSPEND_MAX) {
  
          error = pm_suspend(state);      // 常规挂起    } else if (state == PM_SUSPEND_MAX) {
  
          error = hibernate();            // 休眠到磁盘    } else {
  
          error = -EINVAL;                // 无效状态    }out:    // 4. 释放锁并返回结果    pm_autosleep_unlock();    return error ? error : n;}power_attr (状态);

power_attr定义了一个名称为状态的属性文件,该文件的存储接口为state_store,该接口在锁定住自动休眠功能后,解析用户传入的缓冲器(冷冻,备用或MEM),转换成状态参数。

状态参数的类型为suspend_state_t,在包括\ linux \ suspend.h中定义,为电源管理状态在内核中的表示。具体如下:​​​​​​​

typedef int __suspend_state_t;#define PM_SUSPEND_ON         ((__force suspend_state_t)0)#define PM_SUSPEND_FREEZE     ((__force suspend_state_t)1)#define PM_SUSPEND_STANDBY    ((__force suspend_state_t)2)#define PM_SUSPEND_MEM        ((__force suspend_state_t)3)#define PM_SUSPEND_MIN        PM_SUSPEND_FREEZE#define PM_SUSPEND_MAX        ((__force suspend_state_t)4)

根据状态的值,如果不是(PM_SUSPEND_MAX,对应于hibernate功能),则调用pm_suspend接口,进行后续的处理。 

pm_suspend在内核/power/suspend.c定义,处理所有的suspend过程。  

4.2 pm_suspend&enter_state

pm_suspend的实现非常简单,简单的做一下参数合法性判断,直接调用enter_state接口

int pm_suspend(suspend_state_t state){
  
      int error;    // 1. 检查状态有效性    if (state <= PM_SUSPEND_ON || state >= PM_SUSPEND_MAX)        return -EINVAL;    // 2. 进入挂起状态    error = enter_state(state);    // 3. 更新统计信息    if (error) {
  
          suspend_stats.fail++;        dpm_save_failed_errno(error);    } else {
  
          suspend_stats.success++;    }    return error;}

enter_state代码为:​​​​

static int enter_state(suspend_state_t state){
  
      int error;    // 1. 检查状态有效性    if (!valid_state(state))        return -ENODEV;    // 2. 获
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

法迪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值