DSDT
関連記事
DSDT (Differentiated System Description Table) は ACPI 規格の一部です。特定のシステムに対応して電源イベントに関する情報を提供します。ACPI テーブルはメーカーによってファームウェア上に用意されています。Linux で ACPI の機能が使えないというのはよくある問題です。例えば: ファンが稼働しない、フタを閉じたときに画面がオフにならない、など。これらの問題は DSDT が Windows しか考えずに作成されているのが原因で、インストール後にパッチをあてることができます。この記事では問題のある DSDT を解析・再構築して、デフォルトの DSDT をカーネルから置き換える方法を説明します。
基本的に DSDT テーブルは ACPI (電源管理) のイベントがあると実行されるコードです。
目次
はじめに
- ACPI 関連の問題はハードウェアメーカーによってリリースされたファームウェアのアップデートで修正される場合があります。無駄な努力をしなくてもいいように、まずはアップデートされたファームウェアをインストールすることが推奨されます。
- あなたの環境の基幹的なコードを操作することになります。変更を加えるときは万全を期すべきです。また、あらかじめディスクを複製したほうが良いでしょう。
- DSDT に修正をかける前に、以下のショートカットを試すことができます:
カーネルから Windows のバージョンを報告する
カーネルパラメータの acpi_os_name 変数を使ってください。例:
acpi_os_name="Microsoft Windows NT"
もしくは:
acpi_osi="!Windows2012"
上記の設定を GRUB の kernel 行に追加してください。
他にテストできる文字列:
- "Microsoft Windows XP"
- "Microsoft Windows 2000"
- "Microsoft Windows 2000.1"
- "Microsoft Windows ME: Millennium Edition"
- "Windows 2001"
- "Windows 2006"
- "Windows 2009"
- "Windows 2012"
- 上記の全てで駄目なら、"Linux" も試してください。
下の手順で DSDT を展開して .dsl ファイルを検索して、"Windows" を grep して何が表示されるか確認することもできます。
修正済みの DSDT を検索する
DSDT ファイルは本来 ACPI Source Language で書かれています (.asl/.dsl ファイル)。コンパイラを使うことで 'ACPI Machine Language' ファイル (.aml) やヘックステーブル (.hex) が生成できます。ファイルを Arch に組み入れるには、コンパイル済みの .aml ファイルを手に入れる必要があります。自分でコンパイルするか、あるいはインターネット上の誰かを自己責任で信頼するかです。インターネットからファイルをダウンロードした場合、大抵は圧縮済みの .asl ファイルになっています。ファイルを unzip してコンパイルしてください。インターネットからダウンロードすることの利点はコードの修正について自分で調べなくてもよいということです。
Arch ユーザーで同じノートパソコンを使っているというのは少数派のうちの少数派になります。同じ機種について情報がないか他のディストリや Linux のフォーラムも検索してみてください。技術に精通した人が大勢居るところなら同じ問題が見つかって、誰かが作った DSDT が発見できる、あるいはコンパイル済みのバージョンがあるかもしれません (自己責任で使ってください)。検索エンジンが最良のツールです。検索キーワードは短くしましょう: '機種名' + 'dsdt' で結果が得られるはずです。
自分で再コンパイルする
再コンパイルするときは Gentoo wiki, ACPI Spec ホームページ, Linux ACPI Project にある資料が役に立ちます。簡単に説明すると、Intel の ASL コンパイラを使うことでシステムの DSDT テーブルをソースコードに変換できるので、エラーがないか調査・修正してから再コンパイルします。手順は Gentoo wiki に詳しく記載されています。コードを修正するには iasl をインストールする必要があります。また、インストールするにはカーネルのコンパイルが必要です。
システムの DSDT が Intel と Microsoft のコンパイラどちらを使ってコンパイルされたのか確認してください:
$ dmesg|grep DSDT
ACPI: DSDT 00000000bf7e5000 0A35F (v02 Intel CALPELLA 06040000 INTL 20060912) ACPI: EC: Look up EC in DSDT
Microsoft のコンパイラが使われている場合、INTL という省略形が MSFT になります。DSDT を逆コンパイル・再コンパイルするときにエラーが発生したら、Google で検索したり ACPI の仕様にあたって修正してください。使用しているコンパイラのバージョンが違うためにエラーが起こる場合、起動時に ACPICA が対処することがあります。カーネルの ACPICA コンポーネントは DSDT をコンパイルするときに発生する些細なエラーに大抵は対処してくれます。システムがちゃんと動作しているのであれば、コンパイルエラーにあまり悩む必要はありません。
- ACPI テーブルを (root で) 展開:
# cat /sys/firmware/acpi/tables/DSDT > dsdt.dat
。
- 逆コンパイル:
iasl -d dsdt.dat
。
- 再コンパイル:
iasl -tc dsdt.dsl
。
- エラーを確認して:
dsdt.dsl 6727: Name (_PLD, Buffer (0x10) Error 4105 - Invalid object type for reserved name ^ (found BUFFER, requires Package)
- 修正:
$ nano +6727 dsdt.dsl
(_PLD, Package(1) {Buffer (0x10)...
- 修正したコードをコンパイル:
iasl -tc dsdt.dsl
(-ic オプションを使うことで C のインクルードファイルをカーネルのソースに挿入できます)。
エラーや警告が表示されなければ完了です。
修正済みのコードを使う
カスタム DSDT を使う方法は2つあります:
- カーネルに組み入れてコンパイルする
- 起動時にロードする (サポートされていません)
カーネルにコンパイル
カスタムカーネルをコンパイルする方法をよく読んでください。一番簡単なのは"伝統的な"方法です。DSDT をコンパイルした後、iasl は2つのファイルを生成します: dsdt.hex
と dsdt.aml
。
menuconfig
を使う:
- "Device Drivers -> Generic Driver Options" の "Select only drivers that don't need compile-time external firmware" を無効化してください。
- "Power management and ACPI options -> ACPI (Advanced Configuration and Power Interface) Support" にある "Include Custom DSDT" を有効化して、修正済みの DSDT ファイル (
dsdt.aml
ではなくdsdt.hex
) の絶対パスを指定してください。
上書きされたことを確認:
dmesg | grep DSDT
を実行。- 上書きされたことを示す文字列を探して下さい。例:
[ 0.000000] ACPI: Override [DSDT- A M I], this is unsafe: tainting kernel [ 0.000000] ACPI: DSDT 00000000be9b1190 Logical table override, new table: ffffffff81865af0 [ 0.000000] ACPI: DSDT ffffffff81865af0 0BBA3 (v02 ALASKA A M I 000000F3 INTL 20130517)
起動時にロード
Arch の標準カーネルはカスタム DSDT の使用をサポートしているため、まずは iasl でコンパイルした .aml ファイルを /boot/dsdt.aml
にコピーしてください。
ブートローダーで DSDT を置き換えるため、カスタム DSDT テーブルをブートローダーのイメージに組み込む必要があります。以下を /etc/grub.d/01_acpi
にコピー (GRUB_CUSTOM_ACPI
は使用する .aml ファイルのパスに置き換えてください):
#!/bin/sh set -e # Uncomment to load custom ACPI table GRUB_CUSTOM_ACPI="/boot/dsdt.aml" # DON'T MODIFY ANYTHING BELOW THIS LINE! prefix=/usr exec_prefix=${prefix} libdir=${exec_prefix}/lib . /usr/share/grub/grub-mkconfig_lib #. ${libdir}/grub/grub-mkconfig_lib # Load custom ACPI table if [ x${GRUB_CUSTOM_ACPI} != x ] && [ -f ${GRUB_CUSTOM_ACPI} ] \ && is_path_readable_by_grub ${GRUB_CUSTOM_ACPI}; then echo "Found custom ACPI table: ${GRUB_CUSTOM_ACPI}" >&2 prepare_grub_to_access_device `${grub_probe} --target=device ${GRUB_CUSTOM_ACPI}` | sed -e "s/^/ /" cat << EOF acpi (\$root)`make_system_path_relative_to_its_root ${GRUB_CUSTOM_ACPI}` EOF fi
ファイルに実行可能権限を付与してください、そうしないと grub-mkconfig によって無視されます:
# chmod +x /etc/grub.d/01_acpi
これで GRUB は DSDT を core.img に組み込みます。
次に新しいブートイメージが必要です。GRUB を使っている場合、以下を実行:
# grub-mkconfig -o /boot/grub/grub.cfg
最後に、initrd を再作成してください:
# mkinitcpio -p linux
再起動すれば変更が適用されます。
新しい DSDT が使われているかどうか確認するには # cat /sys/firmware/acpi/tables/DSDT > dsdt.dat
でテーブルを読み込んで iasl -d dsdt.dat
で逆コンパイルしてください。