wurrrrrrrr
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.

      Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Explore these features while you wait
      Complete general settings
      Bookmark and like published notes
      Write a few more notes
      Complete general settings
      Write a few more notes
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Linux Kernel Power Management kernel 中的電源管理可以分為以下兩類: * Static PM * 主要處理的是系統長時間處於非活動狀態時如何節省電量 * 目前沒有主要的開發工作 * Dynamic PM * 主要處理的是系統處於活動狀態時如何配置系統設備 * 隨著 soc 的發展這個框架在不斷的發展跟調整 ## System Sleep States Linux 核心最多可以支援**四種系統睡眠狀態**,其中包括休眠(hibernation)和最多三種不同的系統掛起(suspend)變體。以下是核心支援的睡眠狀態: ### Suspend-to-Idle 這是一種通用的、純軟體實現的輕量級系統掛起變體(也稱為 S2I 或 S2Idle)。與運行時空閒(runtime idle)相比,這種方法能夠通過凍結用戶空間、暫停時間計算,並將所有 I/O 設備進一步置於低功耗狀態(其功耗可能低於工作狀態下的水平)來實現更高效的能量節省。這樣,處理器在系統掛起期間可以長時間保持在 **deepest idle states** ,最大限度地降低能耗。 系統會通過 **in-band** 中斷 從此狀態中喚醒,因此理論上,任何在工作狀態下能夠產生中斷的設備,也可以被設置為 S2Idle 的喚醒設備。 * In-band 中斷 是指設備通過 正常的數據路徑 在執行常規任務時所產生的中斷。這種中斷與設備的 正常工作流程 相結合,用來觸發系統從 低功耗狀態(如 S0ix)中恢復。 此狀態可以用於不支援 Standby 或 Suspend-to-RAM 的平台,或者它可以與任何更深層的系統掛起變體一起使用,以提供較低的恢復延遲。如果 CONFIG_SUSPEND 內核配置選項已啟用,則始終支援此狀態。 **CONFIG_SUSPEND** CONFIG_SUSPEND 是一個內核配置選項,用於啟用 系統掛起(suspend)功能。當這個選項啟用時,系統將支持掛起操作,並且能夠根據不同的硬體平台進行適當的休眠操作。 因此,S0ix 狀態的使用取決於是否啟用了 `CONFIG_SUSPEND`。如果沒有啟用這個選項,則 S0ix 狀態的機制將無法生效。 ### Standby 此狀態提供了適度但實際的能量節省,同時確保能夠輕鬆地過渡回工作狀態。由於核心邏輯仍保持供電,沒有丟失操作狀態,系統可以從掛起的位置快速恢復並繼續運行。 除了凍結用戶空間、暫停時間計算以及將所有 I/O 設備置於低功耗狀態,此狀態還會將**非啟動 CPU 下線**,並在過渡期間暫停所有低層次的系統功能。因此,相較於掛起至 **suspend-to-idle**,此狀態能夠進一步節省更多的能量,但恢復延遲通常會較長。 在此狀態下,能夠喚醒系統的設備數量通常較掛起至**suspend-to-idle** 為少,並且可能需要依賴平台來設置適當的喚醒功能。 當啟用 CONFIG_SUSPEND 內核配置選項,且平台已註冊對此狀態的支援時,該狀態會被支援。對於基於 [ACPI](https://www.kernel.org/doc/ols/2005/ols2005v1-pages-59-76.pdf)(高級配置與電源接口)的系統,這個睡眠狀態會映射為 [ACPI](https://www.kernel.org/doc/ols/2005/ols2005v1-pages-59-76.pdf) 定義的 S1 系統狀態。 ### Suspend-to-RAM 這個狀態(也稱為 STR 或 S2RAM),如果支援,可以提供顯著的能量節省,因為系統中的所有部分都會進入低功耗狀態,唯獨記憶體會進入自我刷新模式以保留其內容。進入 standby 時執行的所有步驟也會在過渡到 S2RAM 時執行。根據平台的能力,可能會有額外的操作進行。特別是,在基於 [ACPI](https://www.kernel.org/doc/ols/2005/ols2005v1-pages-59-76.pdf) 的系統中,內核會在 S2RAM 過渡的最後一步將控制權交給韌體(BIOS),這通常會導致更多低階元件的關閉,這些元件並非直接由內核控制。 設備和 CPU 的狀態會被保存並保存在記憶體中。所有設備都會被 suspend 並進入低功耗狀態。在許多情況下,當進入 S2RAM 時,所有 peripheral buses 會失去電源,這些外圍總線負責連接系統內的各種設備(如 USB、PCI、網卡、顯示卡等),因此設備必須能夠處理恢復到「開啟」狀態的過渡。 在基於 ACPI 的系統中,S2RAM 需要平台固件中的一些最小啟動程式碼來從此狀態恢復系統。其他平台也可能是如此。 能喚醒系統的設備集合通常會比掛起至空閒和待機狀態少,並且可能需要依賴平台來設置適當的喚醒功能。 如果啟用了 `CONFIG_SUSPEND` 內核配置選項,並且平台已註冊對此狀態的支援,則支援 S2RAM。對於基於 ACPI 的系統,它映射到 ACPI 定義的 S3 系統狀態。 ### Hibernation 這個狀態(**也稱為休眠到磁碟或 STD**)提供了最大的能量節省,並且即使在平台沒有低層次的系統掛起支援的情況下,仍然可以使用。然而,它需要一些低層次的程式碼來恢復系統,這些程式碼必須針對底層的 CPU 架構存在。 休眠(Hibernation)與任何其他系統掛起變體有顯著的不同。將系統進入休眠狀態需要**三個系統狀態變更**,並且恢復則需要**兩個系統狀態變更**。 首先,當觸發休眠時,內核會停止所有系統活動並創建一個記憶體快照影像,將其寫入持久性存儲中。接著,系統會進入一個可以保存快照影像的狀態,該影像被寫入並且最終系統會進入目標低功耗狀態,其中幾乎所有硬體組件,包括內存,都會被切斷電源,只有一小部分喚醒設備仍然保持啟動。 一旦快照影像寫入完成,系統可以進入一個特殊的低功耗狀態(像是 [ACPI](https://www.kernel.org/doc/ols/2005/ols2005v1-pages-59-76.pdf) S4),或者簡單地關閉電源。關閉電源意味著最小的功耗,這使得該機制可以在任何系統上工作。然而,進入特殊的低功耗狀態則可能允許使用額外的系統喚醒方式(例如,按下鍵盤上的某個鍵或打開筆記型電腦的蓋子)。 在喚醒後,控制權會交給平台韌體,該韌體運行一個 boot loader,並啟動一個新的內核實例(控制權也可能直接交給 boot loader ,這取決於系統配置,但無論如何都會啟動一個新的內核實例)。這個新的內核實例(稱為恢復內核)會在持久性存儲中查找休眠影像,如果找到了,就將其載入到記憶體中。接下來,系統的所有活動將停止,並且恢復內核會將自己與影像內容重寫,然後跳轉到影像中存儲的原始內核中的特殊跳板區域(稱為影像內核),這時需要特定於架構的低層次程式碼。最後,影像內核會將系統恢復到休眠前的狀態,並允許用戶空間重新運行。 如果設置了 `CONFIG_HIBERNATION` 內核配置選項,則支援休眠功能。然而,該選項僅能在給定的 CPU 架構支援系統恢復的低層次程式碼的情況下設置。 ## Basic sysfs Interfaces for System Suspend and Hibernation 電源管理子系統提供了一個統一的 sysfs 接口,用於系統睡眠,無論底層系統架構或平台如何。這個接口位於 `/sys/power/` 目錄中,並包含以下屬性(文件): ### state 這個文件包含一個字符串列表,表示內核支援的睡眠狀態。將這些字符串中的一個寫入該文件會使內核開始將系統轉換到該字符串所表示的睡眠狀態 * "disk"、"freeze" 和 "standby" 分別表示hibernation、suspend-to-idle 和 standby 睡眠狀態。 * "mem" 字符串會根據下面描述的 mem_sleep 文件的內容來解釋。 * 如果內核不支援任何系統睡眠狀態,則該文件不會出現。 ``` echo "disk" | sudo tee /sys/power/state ``` ``` echo "freeze" | sudo tee /sys/power/state ``` 在 [linux/kernel/power/suspend.c](https://github.com/torvalds/linux/blob/master/kernel/power/suspend.c) 中可以看到下列這段程式碼: ```c const char * const pm_labels[] = { [PM_SUSPEND_TO_IDLE] = "freeze", [PM_SUSPEND_STANDBY] = "standby", [PM_SUSPEND_MEM] = "mem", }; const char *pm_states[PM_SUSPEND_MAX]; static const char * const mem_sleep_labels[] = { [PM_SUSPEND_TO_IDLE] = "s2idle", [PM_SUSPEND_STANDBY] = "shallow", [PM_SUSPEND_MEM] = "deep", }; ``` ### mem_sleep 這個檔案包含了一個字串列表,表示支援的系統 suspend 變體,並允許使用者空間選擇與上述狀態檔案中的“mem”字串相關聯的 suspend 變體。 這個檔案中可能存在的字串有 “s2idle”、 “shallow” 和 “deep”。其中,“s2idle” 字串始終代表 suspend-to-idle,而依照慣例,“shallow” 和 “deep” 分別代表 standby 和 suspend-to-RAM 。 將其中列出的某個字串寫入此檔案,會使該 suspend 變體與狀態檔案中的“mem”字串相關聯。當前與“mem”字串相關聯的掛起變體會以方括號顯示。 如果內核不支援系統 suspend,則此檔案將不存在。 ``` wu@wu-Pro-E500-G6-WS720T:~$ cat /sys/power/mem_sleep [s2idle] deep wu@wu-Pro-E500-G6-WS720T:~$ echo "deep" | sudo tee /sys/power/mem_sleep deep wu@wu-Pro-E500-G6-WS720T:~$ cat /sys/power/mem_sleep s2idle [deep] wu@wu-Pro-E500-G6-WS720T:~$ echo "s2idle" | sudo tee /sys/power/mem_sleep ``` ### disk 這個文件控制休眠的操作模式。具體來說,它告訴內核在創建休眠影像後應該執行什麼操作。 從這個文件讀取會返回一個編碼的支援選項列表,具體如下: * platform * 將系統置於一個特殊的低功耗狀態(例如 ACPI S4),以便提供額外的喚醒選項,並可能允許平台韌體在喚醒後執行簡化的初始化路徑。 僅當平台提供了一個特殊機制,在創建休眠影像後將系統置於休眠狀態時,這個選項才可用(例如支持 ACPI 的平台通常會這樣做)。 * shutdown * 關閉系統電源。 * reboot * 重啟系統(主要用於診斷)。 * suspend * Hybrid system suspend.將系統置於通過上述 mem_sleep 文件選擇的 suspend 睡眠狀態。如果系統成功從該狀態喚醒,則丟棄休眠影像並繼續運行。否則,使用休眠影像來恢復系統的先前狀態。 如果支持系統 suspend,則此選項可用。 * test_resume * 診斷操作。將影像加載,並假設系統剛剛從休眠中喚醒,當前運行的內核實例是恢復內核,然後進行完整的系統恢復。 當前選中的選項將以方括號顯示,這表示當寫入「disk」到 `/sys/power/state` 時,對應的操作會在創建並保存影像後執行。 **如果內核不支持休眠,則此文件不會出現**。 ``` wu@wu-Pro-E500-G6-WS720T:~$ cat /sys/power/disk [platform] shutdown reboot suspend test_resume ``` ### image_size 此文件控制休眠影像的大小。 它可以被寫入一個表示**非負整數的字符串**,該數字將作為影像大小的最大限制(以字節為單位)。休眠核心會盡力確保影像大小不會超過這個數字,但如果這無法達到,休眠影像仍然會創建,並且其大小會儘可能小。具體來說,寫入 "0" 會將休眠影像的大小設置為最小。 從該文件讀取會返回當前的影像大小限制,默認設置為可用記憶體大小的約 2/5。 ### pm_trace 這個檔案控制著「PM 追蹤」機制,將最後一次的 suspend 或 resume 事件點儲存到 RTC 記憶體中,並且能夠在重新啟動後仍然保留。這有助於更有效地調試由於裝置驅動程式在系統 suspend 或 resume 過程中失敗所引起的硬鎖死或重新啟動(這是較為常見的情況)。 如果它的值為 "1",則每個 suspend /resume 事件的指紋會依序儲存在 RTC 記憶體中(覆蓋實際的 RTC 資訊)。這樣,即使在存儲指紋後系統崩潰,它仍然能夠保留並在之後用來識別造成崩潰的驅動程式。 預設情況下,它的值為 "0",但可以通過寫入代表非零整數的字串來將其改為 "1"。 ### wakeup 閱讀了 [Linux 核心設計: Power Management(1): System Sleep model](https://hackmd.io/@RinHizakura/r17lOaDqp#System-Sleep-states) 發現到還有這個檔案: 不同於上述可見的 sysfs 節點是對於整個 PM 子系統的控制方式。每個由 PM 子系統管理的裝置可以有各異的 PM 功能支援,可由 `/sys/devices/.../power/` 路徑下的檔案取得相關資訊或更改配置。 有些裝置可以被用來觸發喚醒系統的事件,使系統退出睡眠狀態。例如透過對鍵盤輸入或者按下開機按鍵,讓系統從睡眠中恢復。與此功能相關的檔案是 `/sys/devices/.../power/wakeup`。 ```c struct dev_pm_info { unsigned int can_wakeup:1; ... struct wakeup_source *wakeup; ``` 要在 Linux 核心中使裝置能被用來喚醒系統的睡眠狀態,驅動程式需先使用 `device_set_wakeup_capable()` 來設置裝置對應的 `struct device` 下的 `power.can_wakeup` 欄位。這表示裝置首先在物理上可支援此功能。 `power.wakeup` 則是一個 `struct wakeup_source` 的指標,定義了當將裝置作為喚醒系統的觸發來源時,如何把喚醒事件通知到 PM core 的程式碼實作,使後者能夠將整個系統都恢復到運作狀態。 當裝置在硬體上能夠支援系統喚醒,且在核心中也提供 `power.wakeup` 的實作並由 `device_set_wakeup_capable` 啟用,在 userspace 的 `/sys/devices/.../power/` 路徑下就可以看到 wakeup 檔案。在 userspace 可以向其中寫入 "enabled" 或者 "disabled" 來決定是否要將該裝置作為喚醒訊號的提供者。 留意到系統的喚醒與 runtime PM 時談論的 remote wakeup 不同。雖然有些情況兩者在物理上是透過一樣的機制,但 Remote wakeup 主要是指在低功耗狀態的裝置可以觸發特定中斷,以通知系統應將其置於全速狀態的功能。但這些中斷在系統進入睡眠時不一定能夠觸發。 可以輸入下列指令來找尋 wakeup 檔案 ``` $ find /sys/devices/ -name wakeup ``` 當找到後能輸入來查看是位於 /sys/devices/.../ 路徑下的設備)當系統處於休眠狀態時,能否用來喚醒系統。 ``` cat /sys/devices/.../power/wakeup ``` 例子( disabled ): ``` wu@wu-Pro-E500-G6-WS720T:~$ cat /sys/devices/pci0000:00/0000:00:1f.3/power/wakeup disabled ``` 例子( enabled ): ``` wu@wu-Pro-E500-G6-WS720T:~$ cat /sys/devices/platform/rtc_cmos/rtc/rtc0/alarmtimer.0.auto/power/wakeup enabled ```

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Google Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully