1. 程式人生 > >Linux Kernel and Android 休眠與喚醒(中文版)

Linux Kernel and Android 休眠與喚醒(中文版)

現在, 所有的程序(也包括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進入 省電狀態. 這時候,就已經休眠了.程式碼的執行也就停在這裡了.