這也造成了在linux kernel原始碼中,有著像asus-laptop.c、thinkpad_acpi.c…等,這類專為各大廠不同型號的筆記型電腦處理熱鍵的module,而每個module中又有可能要對每個型號對不同的處理。除了這些modules,甚至連atkbd.c中都有很多的quirk,來處理各種型號筆記型電腦上的熱鍵(forced release key event)。
※
一種常見的情況是:當按下熱鍵時,既收不到scancode、也收不到ACPI event,看起來就像是linux kernel完全無法從硬體收到任何訊息。但是熱鍵在Windows中是可以用的,所以硬體是正常的。這種情況真是讓人完全找不到頭緒可以從何下手來debug。
不過這樣的bug其實還是有跡可循,我們可先猜測熱鍵是由embedded controller(EC)控制的,利用下列的方法來確認:
首先先找出EC的GPE編號:
$ dmesg | grep EC
ACPI: EC: GPE = 0x11, I/O: command/status = 0x66, data = 0x62
看一下目前interrupt的數字:
$ cat /sys/firmware/acpi/interrupts/gpe11
10608 enabled
此時,按一下熱鍵,再看看interrupt的數字有無增加。如果interrupt的數字增加了,應該就可以判斷那個熱鍵是由EC控制的。
有時候EC也會送一些非熱鍵產生的interrupt,這就只能多靠眼力來觀察。
※
到這裡,我們就可以把責任歸咎於EC。因為理論上EC是必須要送出scancode或是ACPI event出來的。那麼EC又為什麼不送scancode或ACPI event出來呢?
在一些情況下,硬體製造商希望這個熱鍵的功能是必須安裝某個特定軟體才會啟動。像是某家廠牌的小筆電,必須對某個io port寫入一次,EC才會正確的送出某一個熱鍵的scancode出來。而這樣的「初始化」是寫在Windows平台上特定bundled的軟體中。Linux沒有這樣的軟體,所以熱鍵會無效。
此時我們可以回報原廠,請他們修改BIOS/EC code,讓熱鍵在Linux下也可以正常工作;如果我們知道EC初始化的方式(不過通常一般使用者不會知道),也可以在某支驅動程式中來初始化EC。而另外的作法是寫一個驅動程式,透過kernel所提供的EC的介面來偵測EC的interrupt。