「DSDT」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
(同期)
 
(3人の利用者による、間の5版が非表示)
49行目: 49行目:
   
 
== 自分で再コンパイルする ==
 
== 自分で再コンパイルする ==
再コンパイルするときは [http://www.acpi.info ACPI Spec ホームページ] や [https://01.org/linux-acpi Linux ACPI Project] にある資料が役に立ちます。簡単に説明すると、Intel の ASL コンパイラを使うことでシステムの DSDT テーブルをソースコードに変換できるので、エラーがないか調査・修正してから再コンパイルします。コードを修正するには {{Pkg|iasl}} をインストールする必要があります。また、インストールするには[[カーネル#コンパイル|カーネルのコンパイル]]が必要です。
 
   
  +
この取り組みにおける最良のリソースは、[https://uefi.org/acpi/specs ACPI Spec ホームページ] および [https://01.org/linux-acpi Linux ACPI プロジェクト] になります。これは、''acpi.sourceforge.net'' で発生したアクティビティに優先します。
システムの DSDT が Intel と Microsoft のコンパイラどちらを使ってコンパイルされたのか確認してください:
 
  +
簡単に言うと、Intel の ASL コンパイラーを使用して、システムの DSDT テーブルをソースコードに変換し、エラーを特定して修正し、再コンパイルすることです。
{{hc|<nowiki>$ dmesg|grep DSDT</nowiki>|
 
  +
  +
コードを変更するには、{{Pkg|acpica}} をインストールする必要があります。
  +
  +
システムの DSDT が Intel と Microsoft のコンパイラ'''どちらを使ってコンパイルされたのか確認してください''':
  +
{{hc|# dmesg {{!}} grep DSDT|
 
ACPI: DSDT 00000000bf7e5000 0A35F (v02 Intel CALPELLA 06040000 INTL 20060912)
 
ACPI: DSDT 00000000bf7e5000 0A35F (v02 Intel CALPELLA 06040000 INTL 20060912)
 
ACPI: EC: Look up EC in DSDT
 
ACPI: EC: Look up EC in DSDT
58行目: 62行目:
 
Microsoft のコンパイラが使われている場合、INTL という省略形が MSFT になります。DSDT を逆コンパイル・再コンパイルするときにエラーが発生したら、Google で検索したり ACPI の仕様にあたって修正してください。使用しているコンパイラのバージョンが違うためにエラーが起こる場合、起動時に ACPICA が対処することがあります。カーネルの ACPICA コンポーネントは DSDT をコンパイルするときに発生する些細なエラーに大抵は対処してくれます。システムがちゃんと動作しているのであれば、コンパイルエラーにあまり悩む必要はありません。
 
Microsoft のコンパイラが使われている場合、INTL という省略形が MSFT になります。DSDT を逆コンパイル・再コンパイルするときにエラーが発生したら、Google で検索したり ACPI の仕様にあたって修正してください。使用しているコンパイラのバージョンが違うためにエラーが起こる場合、起動時に ACPICA が対処することがあります。カーネルの ACPICA コンポーネントは DSDT をコンパイルするときに発生する些細なエラーに大抵は対処してくれます。システムがちゃんと動作しているのであれば、コンパイルエラーにあまり悩む必要はありません。
   
  +
バイナリ ACPI テーブルを抽出します:
* ACPI テーブルを (root で) 展開: {{ic|# cat /sys/firmware/acpi/tables/DSDT > dsdt.dat}}。
 
   
  +
{{bc|# cat /sys/firmware/acpi/tables/DSDT > dsdt.dat}}
* 逆コンパイル: {{ic|iasl -d dsdt.dat}}。
 
   
  +
ACPI テーブルを ''.dsl'' ファイルに逆アセンブルします:
* 再コンパイル: {{ic|iasl -tc dsdt.dsl}}。
 
   
  +
{{bc|$ iasl -d dsdt.dat}}
* エラーを確認して:
 
dsdt.dsl 6727: Name (_PLD, Buffer (0x10)
 
Error 4105 - Invalid object type for reserved name ^ (found BUFFER, requires Package)
 
*修正:
 
{{hc|$ nano +6727 dsdt.dsl|(_PLD, Package(1) {Buffer (0x10)...}}
 
   
  +
''.dsl'' ファイルから 16 進 AML テーブル (C 言語) を作成してみます:
* OEM バージョンを増やしてカーネルが修正した ACPI テーブルを認識するようにする。修正前:
 
  +
  +
{{bc|$ iasl -tc dsdt.dsl}}
  +
  +
16 進 AML テーブルの作成時に出力されたエラーを調べて修正します。例えば:
  +
  +
{{bc|
  +
dsdt.dsl 6727: Name (_PLD, Buffer (0x10)
  +
Error 4105 - Invalid object type for reserved name ^ (found BUFFER, requires Package)
  +
}}
  +
  +
エラーが発生したファイルの行 6727 を修正します:
  +
  +
{{bc|
  +
(_PLD, '''Package(1) {'''Buffer (0x10)
  +
{
  +
...
  +
}'''}''')
  +
}}
  +
  +
OEM バージョンを上げます。そうしないと、カーネルは変更された ACPI テーブルを適用しません。たとえば、OEM バージョンを増やす前に、次のようにします:
   
 
{{bc|DefinitionBlock ("DSDT.aml", "DSDT", 2, "INTEL ", "TEMPLATE", 0x00000000)}}
 
{{bc|DefinitionBlock ("DSDT.aml", "DSDT", 2, "INTEL ", "TEMPLATE", 0x00000000)}}
   
  +
OEM バージョンを上げた後:
修正後:
 
  +
  +
{{bc|DefinitionBlock ("DSDT.aml", "DSDT", 2, "INTEL ", "TEMPLATE", 0x0000000'''1''')}}
   
  +
すべてのエラーを修正し、OEM バージョンを上げた後、16 進 AML テーブルを再度作成します:
{{bc|DefinitionBlock ("DSDT.aml", "DSDT", 2, "INTEL ", "TEMPLATE", 0x00000001)}}
 
   
  +
{{bc|$ iasl -tc dsdt.dsl}}
* 修正したコードをコンパイル: {{ic|iasl -tc dsdt.dsl}} (-ic オプションを使うことで C のインクルードファイルをカーネルのソースに挿入できます)。
 
   
  +
C インクルードファイルをカーネルソースに挿入するためのオプション {{ic|-ic}} を試してみるとよいでしょう。エラーや警告が発生しなければ、問題なく実行できます。
エラーや警告が表示されなければ完了です。
 
   
 
== 修正済みのコードを使う ==
 
== 修正済みのコードを使う ==
86行目: 108行目:
 
{{Warning|BIOS をアップデートしたら DSDT を再度修正する必要があります。}}
 
{{Warning|BIOS をアップデートしたら DSDT を再度修正する必要があります。}}
   
カスタム DSDT を使う方法は3つあります:
+
カスタム DSDT を使う方法は2つあります:
 
* ブートローダーによってロードされる CPIO アーカイブを作成する
 
* ブートローダーによってロードされる CPIO アーカイブを作成する
 
* カーネルに組み入れてコンパイルする
 
* カーネルに組み入れてコンパイルする
* 起動時にロードする (サポートされていません)
 
   
 
=== CPIO アーカイブを使う ===
 
=== CPIO アーカイブを使う ===
  +
 
この方法ではカーネルを再コンパイルする必要がなく、カーネルをアップデートしても再度修正を行う必要がありません。
 
この方法ではカーネルを再コンパイルする必要がなく、カーネルをアップデートしても再度修正を行う必要がありません。
   
123行目: 145行目:
 
* "Power management and ACPI options -> ACPI (Advanced Configuration and Power Interface) Support" にある "Include Custom DSDT" を有効化して、修正済みの DSDT ファイル ({{ic|dsdt.aml}} ではなく {{ic|dsdt.hex}}) の絶対パスを指定してください。
 
* "Power management and ACPI options -> ACPI (Advanced Configuration and Power Interface) Support" にある "Include Custom DSDT" を有効化して、修正済みの DSDT ファイル ({{ic|dsdt.aml}} ではなく {{ic|dsdt.hex}}) の絶対パスを指定してください。
   
=== 起動時にロード ===
+
=== GRUB での AML の使用 ===
{{Warning|DSDT フックは削除されたため、mkinitcpio を使う方法はもはやサポートされていません。[https://bugs.archlinux.org/task/27906] を参照。}}
 
Arch の標準カーネルはカスタム DSDT の使用をサポートしているため、まずは iasl でコンパイルした ''.aml'' ファイルを {{ic|/boot/dsdt.aml}} にコピーしてください。
 
   
  +
[[GRUB]] を使用すると、さらに簡単な方法を使用できます。上記で作成した ''.aml'' ファイルをブート パーティションにコピーします:
ブートローダーで DSDT を置き換えるため、カスタム DSDT テーブルをブートローダーのイメージに組み込む必要があります。以下を {{ic|/etc/grub.d/01_acpi}} にコピー ({{ic|GRUB_CUSTOM_ACPI}} は使用する .aml ファイルのパスに置き換えてください):
 
   
  +
# cp dsdt_patch.aml /boot
#!/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 設定に次の行を追加します:
ファイルに実行可能権限を付与してください、そうしないと ''grub-mkconfig'' によって無視されます:
 
# chmod +x /etc/grub.d/01_acpi
 
   
  +
acpi /dsdt_patch.aml
これで GRUB は DSDT を core.img に組み込みます。
 
   
  +
たとえば、これを {{ic|1=/etc/grub.d/40_custom}} に追加します。後で GRUB 設定を生成することを忘れないでください。
次に新しいブートイメージが必要です。GRUB を使っている場合、以下を実行:
 
# grub-mkconfig -o /boot/grub/grub.cfg
 
   
  +
=== 上書きされたことを確認 ===
最後に、initrd を再作成してください:
 
# mkinitcpio -p linux
 
   
  +
上書きされたことを示す文字列を探して下さい。例:
再起動すれば変更が適用されます。
 
   
  +
{{hc|# dmesg {{!}} grep ACPI|
新しい DSDT が使われているかどうか確認するには {{ic|# cat /sys/firmware/acpi/tables/DSDT > dsdt.dat}} でテーブルを読み込んで {{ic|iasl -d dsdt.dat}} で逆コンパイルしてください。
 
  +
[ 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)
* {{ic|<nowiki>dmesg | grep DSDT</nowiki>}} を実行。
 
  +
}}
* 上書きされたことを示す文字列を探して下さい。例:
 
 
[ 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)
 
   
 
== 参照 ==
 
== 参照 ==
   
 
* [https://www.kernel.org/doc/Documentation/acpi/initrd_table_override.txt Upgrading ACPI tables via initrd]
 
* [https://www.kernel.org/doc/Documentation/acpi/initrd_table_override.txt Upgrading ACPI tables via initrd]
  +
* [https://docs.microsoft.com/en-us/windows-hardware/drivers/acpi/winacpi-osi How to Identify the Windows Version in ACPI by Using _OSI]

2024年1月19日 (金) 22:38時点における最新版

関連記事

DSDT (Differentiated System Description Table) は ACPI 規格の一部です。特定のシステムに対応して電源イベントに関する情報を提供します。ACPI テーブルはメーカーによってファームウェア上に用意されています。Linux で ACPI の機能が使えないというのはよくある問題です。例えば: ファンが稼働しない、フタを閉じたときに画面がオフにならない、など。これらの問題は DSDT が Windows しか考えずに作成されているのが原因で、インストール後にパッチをあてることができます。この記事では問題のある DSDT を解析・再構築して、デフォルトの DSDT をカーネルから置き換える方法を説明します。

基本的に DSDT テーブルは ACPI (電源管理) のイベントがあると実行されるコードです。

ノート: Linux ACPI プロジェクトの目標はファームウェアに修正を加えなくても Linux が動作できるようにすることです。新しいカーネルでも DSDT の修正が必要なときはバグレポートを送信してください。

はじめに

  • 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' で結果が得られるはずです。

自分で再コンパイルする

この取り組みにおける最良のリソースは、ACPI Spec ホームページ および Linux ACPI プロジェクト になります。これは、acpi.sourceforge.net で発生したアクティビティに優先します。 簡単に言うと、Intel の ASL コンパイラーを使用して、システムの DSDT テーブルをソースコードに変換し、エラーを特定して修正し、再コンパイルすることです。

コードを変更するには、acpica をインストールする必要があります。

システムの 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 テーブルを抽出します:

# cat /sys/firmware/acpi/tables/DSDT > dsdt.dat

ACPI テーブルを .dsl ファイルに逆アセンブルします:

$ iasl -d dsdt.dat

.dsl ファイルから 16 進 AML テーブル (C 言語) を作成してみます:

$ iasl -tc dsdt.dsl

16 進 AML テーブルの作成時に出力されたエラーを調べて修正します。例えば:

dsdt.dsl   6727:                         Name (_PLD, Buffer (0x10)  
Error    4105 -          Invalid object type for reserved name ^  (found BUFFER, requires Package)

エラーが発生したファイルの行 6727 を修正します:

(_PLD, Package(1) {Buffer (0x10)
{
    ...
}})

OEM バージョンを上げます。そうしないと、カーネルは変更された ACPI テーブルを適用しません。たとえば、OEM バージョンを増やす前に、次のようにします:

DefinitionBlock ("DSDT.aml", "DSDT", 2, "INTEL ", "TEMPLATE", 0x00000000)

OEM バージョンを上げた後:

DefinitionBlock ("DSDT.aml", "DSDT", 2, "INTEL ", "TEMPLATE", 0x00000001)

すべてのエラーを修正し、OEM バージョンを上げた後、16 進 AML テーブルを再度作成します:

$ iasl -tc dsdt.dsl

C インクルードファイルをカーネルソースに挿入するためのオプション -ic を試してみるとよいでしょう。エラーや警告が発生しなければ、問題なく実行できます。

修正済みのコードを使う

警告: BIOS をアップデートしたら DSDT を再度修正する必要があります。

カスタム DSDT を使う方法は2つあります:

  • ブートローダーによってロードされる CPIO アーカイブを作成する
  • カーネルに組み入れてコンパイルする

CPIO アーカイブを使う

この方法ではカーネルを再コンパイルする必要がなく、カーネルをアップデートしても再度修正を行う必要がありません。

以下のカーネルコンフィグを有効にしてください (標準の linux パッケージではデフォルトで有効です):

  • ACPI_TABLE_UPGRADE=y (Linux カーネル 4.6 以上)
  • CONFIG_ACPI_INITRD_TABLE_OVERRIDE=y (Linux カーネル 4.5 以下)

詳しくは [1] を見てください。

まず、以下のフォルダを作成:

$ mkdir -p kernel/firmware/acpi

修正した ACPI テーブルを作成した kernel/firmware/acpi フォルダにコピー。例:

$ cp dsdt.aml ssdt1.aml kernel/firmware/acpi

新しく作成した kernel/ フォルダの中で、以下のコマンドを実行:

$ find kernel | cpio -H newc --create > acpi_override

上記のコマンドで修正済みの ACPI テーブルを含む CPIO アーカイブが作成されます。アーカイブを boot ディレクトリにコピーしてください:

# cp acpi_override /boot

最後に、ブートローダーを設定して CPIO アーカイブをロードします。例えば Systemd-boot を使用している場合、/boot/loader/entries/arch.conf は以下のようになります:

title	 Arch Linux
linux	 /vmlinuz-linux
initrd   /acpi_override
initrd	 /initramfs-linux.img
options  root=PARTUUID=ec9d5998-a9db-4bd8-8ea0-35a45df04701 resume=PARTUUID=58d0aa86-d39b-4fe1-81cf-45e7add275a0 ...

設定後は再起動を行ってから結果を確認してください。

カーネルにコンパイル

カスタムカーネルをコンパイルする方法をよく読んでください。一番簡単なのは"伝統的な"方法です。DSDT をコンパイルした後、iasl は2つのファイルを生成します: dsdt.hexdsdt.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) の絶対パスを指定してください。

GRUB での AML の使用

GRUB を使用すると、さらに簡単な方法を使用できます。上記で作成した .aml ファイルをブート パーティションにコピーします:

# cp dsdt_patch.aml /boot

次に、GRUB 設定に次の行を追加します:

acpi /dsdt_patch.aml

たとえば、これを /etc/grub.d/40_custom に追加します。後で GRUB 設定を生成することを忘れないでください。

上書きされたことを確認

上書きされたことを示す文字列を探して下さい。例:

# dmesg | grep ACPI
[    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)

参照