過去のブログを掘り起こして、当時分からずじまいだったことをAIニイの力を借りて解決していくシリーズの1回目です。
第1回目は、2011年11月1日の初めて投稿した記事の内容です。懐かしいね。
そうでもねーか。
2011年の初投稿の末尾に、こんなことを書いていた。
「誰かすごく親切な方がいましたらご教授くださいませませ」
なんとまあ14年の月日が経ったのだけれど、親切な人は現れなかった。
当時の謎というのは、同じノートPCなのになぜかシャットダウンの挙動がディストリビューションによって違うというやつだ。
Ubuntu、Vine、Puppyはちゃんと電源が落ちる。FedoraとCentOSはというと、acpi=offをGRUBに書かないと起動すらしなかった。
書いても「電源を切る準備ができました」状態で止まる、というものだった。
まずACPIというものについて
ACPIというのはOSとハードウェアの間で電源管理をやりとりするための共通規格で、「シャットダウンしてくれ」「スリープしてくれ」「CPUの温度はいくらだ」といった会話をするための共通言語みたいなものだ。
で、このACPIの仕様を記述したデータがBIOSの中に入っていて、DSDTという名前がついている。ハードウェアの取扱説明書みたいなもので、OSはこれを読んで「このマシンはこういう構造なのね」と理解する。
問題はここからで、当時の安価なノートPCのBIOSというのはわりとざっくり言うと「Windowsで動けばいい」という設計で作られていた。らしい。
Windowsは長年の経験から「多少おかしなDSDTでも動くように」という互換処理を大量に持っていて、行儀の悪いDSDTをうまく受け流す達人だった。一方でLinuxはその許容度がまるで違った。
Ubuntu、Vine、Puppyがシャットダウンできた理由はそれぞれ事情が違う。
Ubuntuはハードウェア互換性をかなり重視していて、行儀の悪いBIOSに対する回避コード、Quirksというらしいが、それをどんどん取り込んでいた。「相手がおかしくてもOS側で吸収する」という思想だ。
Vineは日本製なので、日本向けOEM製品との互換性を意識したパッチが当たっていた可能性が高い。ドスパラのノートとの相性が良かったのはそのあたりかもしれない。
Puppyは軽量化のために複雑なACPI処理をシンプルに実装していたのだが、それが結果として「厳密にACPI規格を解釈しない」動作になり、バグのあるBIOSでも柔軟に対応できた。シンプルさが逆に互換性を生んだ、という皮肉な話だ。
FedoraとCentOSはどちらもRed Hat系で、これが共通点になっている。
FedoraはACPIの規格実装にかなり厳格で「規格通りに動くべき」という思想が強い。らしい。
規格外のBIOSには妥協しない。正しいことをしようとして、逆に動かなかったわけだ。正義感が強すぎて融通が利かない感じというか。
CentOSはそもそもサーバー用途なので、ノートPCの電源管理への最適化が薄く、枯れた安定カーネルを採用していた。ノートPC特有のバグ回避コードが入っていなかった可能性が高い。サーバーにノートPC特有の問題なんぞ知らんということだ。
| Dist | DSDTへの態度 | 結果 |
|---|---|---|
| Ubuntu | おかしくても吸収する | O |
| Vine | クセを吸収 | O |
| Puppy | そもそも読む量が少ない | O |
| Fedora | 規格外なら拒否 | X |
| CentOS | 最適化なし | X |
acpi=off の話に戻ると。
これはカーネルに「BIOSのACPI情報を一切無視してくれ」という指示で、起動時のフリーズはDSDTを読んだ瞬間に壊れた情報を処理しようとして起きていた可能性が高いのだが、acpi=off はそれを丸ごと回避する。
ただし代償がある。
ACPIにはS0〜S5という電源の状態を定義したステートがあって、shutdown -h nowというのはS5ステートへの移行命令をACPIを通じてハードウェアに送ることで実現している。acpi=offにするとその通り道が断たれる。
橋を封鎖したら、荷物も届かなくなった。
「電源を切る準備ができました」で止まるのはそういうことだった。
余談になるが、当時のLinuxにはDSDTオーバーライドという機能があって、壊れたBIOSのDSDTを自前で修正したものに差し替えるという荒技ができた。これを使えばacpi=off なしで起動でき、シャットダウンも問題なくできた可能性がある。らしい。
今読んでもよくわからん。物理的に検証できないというのもあるよね。
LPICの勉強を続けていく過程で分かるといいなぁなんて書いていたけれど、AIによって解決したのでした。めでたしめでたし。