linux 電源管理

ACPI共有六種狀態,分別是S0到S5,它們代表的含義分別是:
  S0--實際上這就是我們平常的工作狀態,所有設備全開,功耗一般會超過80W;
  S1--也稱爲POS(Power on Suspend),這時除了通過CPU時鐘控制器將CPU關閉之外,其他的部件仍然正常工作,這時的功耗一般在30W以下。In this state, no system context is lost (CPU or chip set) and hardware maintains all system context.
  S2--這時CPU處於停止運作狀態,總線時鐘也被關閉,但其餘的設備仍然運轉。This state is similar to the S1 sleeping state except that the CPU and system cache context is lost
  S3--這就是我們熟悉的STR(Suspend to RAM),這時的功耗不超過10W。all system context is lost except system memory. CPU, cache, and chip set context are lost in this state.
  S4--也稱爲STD(Suspend to Disk),這時系統主電源關閉,硬盤存儲S4前數據信息,所以S4是比S3更省電狀態。It is assumed that the hardware platform has powered off all devices. Platform context is maintained.
  S5--這種狀態是最乾脆的,就是連電源在內的所有設備全部關閉,即關機(shutdown),功耗爲0。

 

linux支持3種ACPI的節電模式:

1. S1 - POS standby, power on standby 顯示屏斷電,主機通電

2. S3 - STR standby, (supend to ram) 掛起到內存,鍵盤不能喚醒,需要從電源鍵喚醒

3. S4 -hibernate (supend to disk)掛起到硬盤,需要從硬盤恢復

 

可以簡化爲 sleep 分爲standby 和mem, hibernate即disk分爲shutdown和platform(shutdown將系統狀態保存到磁盤,BIOS關閉計算機;platform同時點亮掛起指示燈)

For device driver, linux takes S1/S3 exactly the same. The difference is in linux kernel, but NOT the driver. The kernel does different things for S1 and S3.

 

cat /sys/power/state   檢查內核支持哪些節電模式,有standby,mem,disk等

 

linux 設備模型中一條就是爲了電源管理和系統管理,能讓系統以特定的順便遍歷硬件。

linux中休眠主要做三件事情:凍結用戶進程和內核任務;調用註冊的設備的suspend回調函數;休眠核心設備和CPU

 

# echo standby > /sys/power/state

用戶對於/sys/power/state 的讀寫會調用到main.c中的state_store(),

1. 同步文件系統

2. 關掉用戶態的helper進程,並調用suspend_freeze_processes()凍結所有的進程

3. 調用suspend_devices_and_enter()休眠所有的外設。在這個函數中, 先對於dpm_list(device_add中調用device_pm_add時添加)中的每個設備調用dpm_prepare;然後在dpm_suspend()中對於dpm_list中所有的設備調用device_suspend()。device_suspend依次調用class->pm, type->pm, bus->pm。譬如pci總線,bus->pm是pci_bus_type的pci_pm_suspend。這個函數判定如果legacy pci的話(即在pci_driver中指定了suspend、suspend_late、resume、resume_early等)則調用pci_legacy_suspend,會由dev找到pci_dev,然後找到pci_drvier,調用其suspend(即在register_pci_driver中的參數);如果非legacy&(!pm),則pci_disable_enabled_device(寫入非master);如果非legacy並且driver->pm不爲NULL,則調用driver->pm接口(並不調用driver->suspend)。

4. 調用dpm_suspend_enter。禁止所有的irq,對於dmp_list中的設備依照反序調用bus->pm->suspend_noirq,禁用沒啓用的CPU,sysdev_suspend,suspend_ops->enter(state)(要麼acpi_suspend_ops_old,要麼acpi_suspend_ops)。

 

resume 的過程剛好是反向過程。

 

因爲所做的項目用到了多處kernel thread,在處理driver的時候要特別注意。默認情況下,所有的kernel thread並不能freeze(用戶態的都可以),只有顯示調用了set_freezable的纔可以(去掉PF_NOFREEZE標誌,但是不能重新設置PF_NOFREEZE標誌)。kernel thread通過調用try_to_freeze進入睡眠(或者通過調用wait_event_freezable來調用try_to_freeze),如果try_to_freeze返回error,則整個hibernation過程失敗。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章