Linux那些事儿之我是Hub(25)不说代码说理论 .

电源管理其实发展挺多年了,也算是比较成熟了,主流的技术有两种,APM和ACPI,APM,即Advanced Power Management,高级电源管理,ACPI,即Advanced Configuration and Power Interface,高级配置和电源接口。

相比之下,APM容易实现,但是,APM属于一个BIOS的spec,也就是说需要BIOS的支持。这种情况过去在笔记本电脑中比较普遍,不过自从ACPI横空出世之后,APM就将走向没落了,并被行家认为将在不久的将来从市场中消失,毕竟一种特性依赖于BIOS不是什么好事,这个时代强调的是独立。

APM是盖茨他们家和Intel一起于1992年提出的,而ACPI则是多了一家小日本的企业,东芝+Intel+Microsoft,这三家于1996年提出了ACPI 1.0,Microsoft的Windows2000也是第一个支持ACPI的操作系统。很显然,ACPI是更为先进的技术,它提供了更为灵活的接口,功能也更为强大,它最有型的地方大概就在于它基本不需要BIOS插手,基本可以通过OS来搞定。它的出现就是为了替代APM,或者说为了克服APM的不足。

在如今的Linux发行版里,基本上你可以自己选择使用这两种电源管理的方式,默认应该是ACPI。选择了其中一种就得关掉另一种,不可能说两种方法同时使用,道理很简单,古训有云:一山不能容二虎,除非一公和一母。(顺便友情提醒,电源管理只是ACPI的功能中的一部分,除此以外,ACPI还有很多别的功能,干了不少和BIOS抢饭碗的事情。)

比如Red Hat中我们进入setup就可以看到系统服务里面有一个叫做acpid的,还有一个叫做apmd的,就是与这两种电源管理方式对应的服务进程。打开了一个就不要再打开另一个,如图2.25.1所示。

Linux那些事儿之我是Hub(25)不说代码说理论 ._第1张图片 
(点击查看大图)图2.25.1  电源管理配置

首先必须知道第一个概念,Linux中的电源管理作为一个子系统(subsystem),它是一个系统工程,这个工程规模大,波及范围广,技术复杂,建设周期长,材料设备消耗大,施工生产流动性强,受自然和社会环境因素影响大。

别以为我这样说很夸张,我们都知道Linux 2.6内核一个最伟大的变化就是建立了一个新的统一的设备模型,可是你知道当年区领导决定建立这个设备模型的初衷是什么吗?就是为了让电源管理工作变得更加容易。("The device model was originally intended to make power management tasks easier through the maintenance of a representation of the host system's hardware structure.")只不过后来写代码的兄弟们走火入魔,踏上了一条不归路,把这个设备模型做得偏离了最初的方向,然而不曾想做出来的东西意义更大了,不仅解决了电源管理的复杂性,而且把所有的设备管理任务都给集中起来了。

那么我们先抛出几个问题,第一,电源管理的含义是什么?省电。具体来说,电源管理意味着让世界充满爱的同时,让所有设备处于尽可能低的耗电状态。如果你计算机中某些部分没有被使用,那么就把它关闭(比如显示器)或者让它进入省电的睡眠模式(比如硬盘)。

其次,什么情况设备要挂起呢?比如,合上笔记本,又比如用户自己定义了一个系统电源管理策略(像30分钟没有console活动的话就挂起),再比如设备自身有它的电源管理游戏规则(像一个设备五分钟没有活动的话就挂起)。于是这就意味着有几种可能:一种是系统级的,即当你合上笔记本的时候,OS负责通知所有的驱动程序,告诉它,需要suspend,即驱动程序提供的suspend函数会被调用,这种情况在江湖上被人叫做system pm,也叫System Sleep Model。

另一种情况,不是系统级的,设备级的,就是说我虽然没有合上笔记本,但就单个设备而言,如果我用户希望这个设备处于低耗电的状态,那么驱动程序也应该能够支持,这种情况被道上的兄弟称之为runtime pm,即Runtime Power Management Model。换句话说,我不管别的设备死还是活,总之我这个设备自己想睡就睡,睡到自然醒,谁也别烦我。

因此,第三,从设备驱动的角度来说,我们应该如何作出自己应有的贡献呢?众所周知,电源管理最重要的两个概念就是suspend和resume,即挂起和恢复。而设备驱动被要求保存好设备的上下文,即在挂起的时候,你作为设备驱动,你得保存好设备的一切状态信息,而在resume的时候,你要能够负责恢复这些信息。所以,你必须申请相关的buffer,把东东存在里面,关键的时候拿出来恢复。总的来说,suspend这个过程就是,上级下命令通知driver,driver保存状态,然后执行命令。即notify before save state; save state before power down。而resume这个过程则是,power on and restore state。

第四,刚才说了,建立统一设备模型的初衷是为了打造更佳的电源管理模型,这究竟是如何体现的呢?我们说过,2.6的内核,不管你是USB还是PCI还是SCSI,最终会有一棵树,会通过父子关系,兄弟关系把所有的设备连接起来,这样做不是为了体现亲情,而是电源管理的基础,因为操作系统需要以一种合理的顺序去唤醒或者催眠一堆的设备,即比如,一个PCI总线上的设备必须在它的父设备睡眠之前先进入睡眠,反过来,又必须在它的父设备醒来以后才能醒来。开源战士范仲淹有一句话把这电源管理机制下的子设备诠释得淋漓尽致:先天下之睡而睡,后天下之醒而醒。

第五,从微观经济学来看,设备挂起意味着什么?意味着没有任何进出口贸易的发生,用英语说这叫,quiesce all I/O,即四个坚持,坚持不进行任何DMA操作,坚持不发送任何IRQ,坚持不读写任何数据,坚持不接受上层驱动发过来的任何请求。

最后提两个术语,STR和STD,这是两种Suspend的状态。STR即Suspend to RAM,挂起到内存,STD就是Suspend to Disk,挂起到磁盘。

STR就是把系统进入STR前的工作状态数据都存放在内存中去。在STR状态下,电源仍然继续为内存和主板芯片组供电,以确保数据不丢失,而其他设备均处于关闭状态,系统的耗电量极低。一旦我们按下Power按钮,系统就被唤醒,马上从内存中读取数据并恢复到STR之前的工作状态,STR的优点是休眠快唤醒也快,因为数据本来就在内存中。

而STD则是把数据保存在磁盘中,很显然,保存在磁盘中要比保存在内存中慢。不过STD最酷的是因为它写到了磁盘中,所以即使电源完全断了,数据也不会丢失。STD就是我们在Windows里面看到的那个Hibernate,即冬眠,或曰休眠,而STR就是我们在Windows里面看到的那个Standby。

STR和STD是计算机休眠的两种主要方式。关于STD,多说两句,我想你永远不会忘记,第一次装Linux的时候,有人要你分区的时候分一个swap分区吧?这里就体现了swap分区的一个作用,如果你安装了Suse操作系统,看你的grub里面,一定有一项类似于resume=/dev/sda4吧,就是断电以后重起了之后,从这个分区里把东西读出来的意思。再补一句,ACPI的状态一共有五种,分别是S1,S2,S3,S4,S5,实际上S4就是STD,而STR就是S3,只不过S1,S2,S3差别不大,不过,在Linux中,S1被叫做Standby,而S3被叫做STR。而S5就是Shutdown在Linux中说挂起,主要说的就是S1,S3和S4。关于S1,S3,S4这三种状态,在/sys/power/state文件里可以有所体现,cat /sys/power/state,你会看到"standby","mem","disk"的字样。

你可能感兴趣的:(Linux那些事儿之我是Hub(25)不说代码说理论 .)