2009年9月14日 星期一

Suspend, Hibernate and Resume 的問題

這類問題因為 BIOS , H/W 每台機器不一樣,可能出問題的部份不一定相同,通常這樣的問題很難有系統的方式去了解原因。
但是這個 [HAL Sleep Quirks] 網站提供了一個偵測的 script ,幫助我們有系統的釐清原因。

以下紀錄以 Asus A8J 遇到的現象和解決的步驟:

安裝 Debian Lenny 後,從 Gnome 選單 |  關機 | 暫停 後,Resume 時會失敗,但是可以從遠端 ssh 回來,所以可能跟顯卡有關...
執行網站上所下載的 quirk-checker.sh ,建議把 iwl3945 無線網路模組先unload,等到 resume 後再 reload,所以 在 /etc/pm/config.d/unload_modules 加上這行:SUSPEND_MODULES="iwl3945"
但這應該不是原因,再進行一次 suspend,還是無法 resume.

研讀 pm-suspend 的參數說明,發現 --quirk-vbe-post 表示 resume 時可以用 bios 相同方式來 reset graphic device 所以試試看:
以 pm-suspend --quirk-post-vbe 來試驗,果然可以正常恢復...

現在修改 /usr/share/hal/fdi/information/10freedesktop 下的檔案.... 最有關的應該是 20-video-quirk-pm-asus.fdi :
由 lshal 指令得到,我們的機器 system.hardware.product=A8JP
找到這一段:
      <match key="system.hardware.product" prefix_outof="A6M;Z84F">
        <merge key="power_management.quirk.vbe_post" type="bool">true</merge>
      </match>

改為:
      <match key="system.hardware.product" prefix_outof="A6M;Z84F;A8JP">
        <merge key="power_management.quirk.vbe_post" type="bool">true</merge>
      </match>
     

如同紅色粗體這樣加入我們的 product ,表示我們要使用 --quirk-vbe-post 的參數即可
改完後,重新啟動 hal :
#> /etc/init.d/hal restart
現在透過 gnome-power-management 進行 suspend, hibernate 都可以正常 resume 回來了。真高興!
Technorati 標籤:


2009年9月3日 星期四

kernel 隨手記 --- 類似 oops 的系統訊息

void __this_fixmap_does_not_exist(void)
{
    WARN_ON(1);
}

在 kernel 裡看到這樣的程式碼,用在哪裡呢?
static __always_inline unsigned long fix_to_virt(const unsigned int idx)
{
    if (idx >= __end_of_fixed_addresses)
        __this_fixmap_does_not_exist();

    return __fix_to_virt(idx);
}
(這裡為了精簡,把註解給拿掉了。)這是不希望發生 if 為真的情形,那如果發生了,就印出像 oops 的狀態,以方便偵錯!所以關鍵在 WARN_ON(1),往下追蹤,發現呼叫到 warn_on_slowpath(__FILE__,__LINE__) 來處理,裡面用了幾個好用的技巧:
1.  __builtin_return_address(0) 請 compiler 找出現在 function 的 return address。
2  sprint_symbol() 可以幫忙找出 symbol name , dump_stack() 可以列印現在的 stack 。
3  這個 WARN_ON() 不像 panic() 會中止系統,理論上,可以用來印出發生問題時的 kernel 狀態 ! 或許在開發 driver 可以用來除錯