ふとしたことから GS60-6QE (→サイト) というスリムな PC を買ったのだが、スリムなのは嬉しいのだけれども黒色アルミボディのせいかわりと熱くなる。 Google 先生に聞いたらもしかするとやりようがあるかもしれないという記事を発見。以下、試される方はくれぐれも自己責任でどうぞ。
ここを見ると、 EC 用の debugfs エントリ ( /sys/kernel/debug/ec/ec0/io ) を使って、温度とファンスピードの対応テーブルを EC の I/O へ直接叩き込む Python スクリプトを作った方がいらっしゃる。 感謝 感謝 感謝 。
内容をみると、 0x6a 〜 0x70 と 0x72 〜 0x78 の対があって前者で温度 (単位摂氏) 後者がそれらに対応するファンスピード (単位 % 、但し 0xff は例外か?) をそれぞれ指定しており、アドレスが 7 バイト分だからつまり 7 段階分を指定できる構造なようだ。そしてもうひとつ 0x82 〜 0x88 と 0x8a 〜 0x90 の対があって、これも同様のフォーマット。
但しこの記事からだけでは前者と後者がどういう区別なのかはよくわからない。異なる 2 箇所にファンが設置されているのか、はたまた Windows 上で Fn + “SHIFT (ギヤチェンジのやつ) ” を使って切り替えるプロファイルに対応しているのか……? それと、 EC のバージョンによってはそのアドレス範囲じゃないような (0x6a 〜 0x70 じゃなくて 0x69 〜 0x6f) というコメントもあって少々気にはなる。
準備
というわけで、実際にやって確かめてみた。 debugfs で EC を書き込み可能でマウントするには、以下のサイトで示しているように ec_sys.ko をロードすることになる :
$ sudo modprobe -r ec_sys
$ sudo modprobe ec_sys write_support=1
起動後の状態
起動後まだ何も変えていない EC レジスタの状態を取得してみたのが以下 :
$ sudo dd if=/sys/kernel/debug/ec/ec0/io bs=1 count=256 | xxd -g1
00000000: 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020: 00 00 00 00 00 00 00 00 00 00 00 80 c0 06 09 4b ...............K
00000030: 03 03 00 0d 51 0a 05 00 cc 10 6a 2c ae 01 80 00 ....Q.....j,....
00000040: 74 09 0e 00 ba 10 91 08 48 02 29 2d bd 0b ce 31 t.......H.)-...1
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 22 00 2f 3c 46 50 5a 5f ........"./<FPZ_
00000070: 64 30 30 37 3e 54 54 54 5b 00 03 05 05 05 05 03 d007>TTT[.......
00000080: 2a 00 37 41 4b 55 5a 5d 5e 00 00 3b 46 54 5b 5b *.7AKUZ]^..;FT[[
00000090: 5b 00 03 04 06 03 03 03 02 16 6e 02 16 65 00 00 [.........n..e..
000000a0: 31 36 48 37 45 4d 53 31 2e 31 30 37 30 35 31 37 16H7EMS1.1070517
000000b0: 32 30 31 36 31 34 3a 32 33 3a 32 33 ba 10 00 40 201614:23:23...@
000000c0: 00 01 25 00 00 9e 40 00 00 64 00 00 00 a4 00 00 ..%...@..d......
000000d0: 00 00 00 00 7f 00 00 00 00 00 00 80 00 00 00 00 ................
000000e0: e2 02 00 00 10 00 00 00 00 00 00 00 00 88 00 00 ................
000000f0: 00 00 80 00 0c 00 0c 00 00 00 00 00 00 00 00 00 ................
これまでの議論から、
- 温度ステップはおおよそ 0x69 か 0x6a あたりから開始し 7 バイト分、基本的に単調に増加する値があるはず
- ファンスピードはおおよそ 0x72 から 7 バイト分、また値は 0x00 から 0x64 そして 0xff で、それ以外の値は無いはず
という予想をすると、多分ひとつ目は 0x69 〜 0x6f と 0x72 〜 0x78 のこれだ :
00000060: 00 00 00 00 00 00 00 00 22 00 2f 3c 46 50 5a 5f
00000070: 64 30 30 37 3e 54 54 54 5b 00 03 05 05 05 05 03
同様に、ふたつ目は 0x81 〜 0x87 と 0x8a 〜 0x90 のこれだろう :
00000080: 2a 00 37 41 4b 55 5a 5d 5e 00 00 3b 46 54 5b 5b
00000090: 5b 00 03 04 06 03 03 03 02 16 6e 02 16 65 00 00
2 対のテーブルの効果
アドレス 0x72 (=114) から 7 バイト分を 0x64 (100%) に、また 0x8a (=138) から 7 バイト分を 0x00 (0%) にして、変化を見てみよう :
$ echo -e -n '\x64\x64\x64\x64\x64\x64\x64' | sudo dd of=/sys/kernel/debug/ec/ec0/io bs=1 seek=114 count=7
$ echo -e -n '\x00\x00\x00\x00\x00\x00\x00' | sudo dd of=/sys/kernel/debug/ec/ec0/io bs=1 seek=138 count=7
……こうすると右側のファンのスピードが上がってくる (変化はとてもゆっくりだが、待てば高速回転になる) 。
逆に、アドレス 0x72 (=114) から 7 バイト分を 0x00 (0%) に、また 0x8a (=138) から 7 バイト分を 0x64 (100%) にすると :
$ echo -e -n '\x00\x00\x00\x00\x00\x00\x00' | sudo dd of=/sys/kernel/debug/ec/ec0/io bs=1 seek=114 count=7
$ echo -e -n '\x64\x64\x64\x64\x64\x64\x64' | sudo dd of=/sys/kernel/debug/ec/ec0/io bs=1 seek=138 count=7
……こうすると右側のファンが停止し (止まるときは即止まる) 、左側のファンのスピードが上がってくる (こちらも変化はとてもゆっくりだが、待てば高速回転になる) 。
つまり、これらをいちいちまとめれば以下のようになる :
[1] 右 (0x69-0x6f:0x72-0x78)
温度: ファン
----------------
0度: 48%
47度: 55%
60度: 62%
70度: 84%
80度: 84%
90度: 84%
91度: 91%
[2] 左 (0x81-0x87:0x8a-0x90)
温度: ファン
----------------
0度: 0%
55度: 59%
65度: 70%
75度: 84%
85度: 91%
90度: 91%
93度: 91%
……ここまでわかれば、あとは最適なテーブルを作って /etc/rc.local あたりで dd すればいいだろう。
参考サイト
- https://askubuntu.com/questions/783069/fan-control-on-msi-laptop-no-pwm-capable-sensors
- https://stackoverflow.com/questions/29440784/writing-to-embedded-controller-registers-in-ubuntu-14-04
- https://www.kernel.org/doc/Documentation/ABI/testing/debugfs-ec
- http://forum.notebookreview.com/threads/msi-gs60-ghost-ghost-pro-thread.742589/page-133#post-9643753