「DSDT」の版間の差分
(→修正済みのコードを使う: 情報を更新) |
Kusanaginoturugi (トーク | 投稿記録) (→参照: add TranslationStatus.) |
||
(2人の利用者による、間の5版が非表示) | |||
111行目: | 111行目: | ||
* ブートローダーによってロードされる CPIO アーカイブを作成する |
* ブートローダーによってロードされる CPIO アーカイブを作成する |
||
* カーネルに組み入れてコンパイルする |
* カーネルに組み入れてコンパイルする |
||
+ | |||
+ | === mkinitcpio の acpi_override フックを使用する === |
||
+ | |||
+ | [[mkinitcpio]] は {{ic|acpi_override}} フックを提供しており、これは {{ic|/usr/initcpio/acpi_override/}} および {{ic|/etc/initcpio/acpi_override/}} にあるすべての ''.aml'' ファイルを取得し、それらを早期に解凍された CPIO アーカイブとして {{ic|/kernel/firmware/acpi/}} 内に配置します。これにより、別途 CPIO アーカイブを手動で作成したり、ブートローダーの設定を変更したりする必要がなくなります。''mkinitcpio'' が非圧縮 CPIO アーカイブをメインの initramfs イメージと一緒に1つのファイルにパッキングするからです。 |
||
+ | |||
+ | まず、{{ic|/etc/initcpio/acpi_override}} ディレクトリを作成し、必要な ''.aml'' ファイルをすべてそこにコピーします。例: |
||
+ | |||
+ | # mkdir /etc/initcpio/acpi_override |
||
+ | # cp dsdt.aml /etc/initcpio/acpi_override/ |
||
+ | |||
+ | 次に、{{ic|/etc/mkinitcpio.conf}} の {{ic|HOOKS}} 配列に {{ic|acpi_override}} を追加します: |
||
+ | |||
+ | {{hc|/etc/mkinitcpio.conf|2= |
||
+ | HOOKS=(... '''acpi_override''') |
||
+ | }} |
||
+ | |||
+ | 最後に、[[Initramfs を再生成]] し、再起動します。 |
||
=== CPIO アーカイブを使う === |
=== CPIO アーカイブを使う === |
||
145行目: | 162行目: | ||
* "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 |
||
+ | === dracut で AML を使用する === |
||
− | 最後に、initrd を再作成してください: |
||
− | # mkinitcpio -p linux |
||
+ | [[Dracut]] を使用している場合、上記で作成した ''.aml'' ファイルを定義された場所にコピーするだけで済みます。対応する設定ファイル {{ic|/etc/dracut.conf.d/acpi-fix.conf}} を作成する必要があります: |
||
− | 再起動すれば変更が適用されます。 |
||
+ | acpi_override="yes" |
||
+ | acpi_table_dir="/usr/local/lib/firmware/acpi" |
||
+ | == オーバーライドが成功したか確認する == |
||
− | 新しい DSDT が使われているかどうか確認するには {{ic|# cat /sys/firmware/acpi/tables/DSDT > dsdt.dat}} でテーブルを読み込んで {{ic|iasl -d dsdt.dat}} で逆コンパイルしてください。 |
||
+ | オーバーライドが成功したことを確認するメッセージを探します。例えば次のようなものです: |
||
− | === 上書きされたことを確認 === |
||
− | * {{ic|<nowiki>dmesg | grep DSDT</nowiki>}} を実行。 |
||
− | * 上書きされたことを示す文字列を探して下さい。例: |
||
+ | {{hc|# dmesg {{!}} grep ACPI| |
||
− | [ 0.000000] ACPI: Override [DSDT- A M I], this is unsafe: tainting kernel |
||
− | + | [ 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) |
||
+ | }} |
||
== 参照 == |
== 参照 == |
||
203行目: | 194行目: | ||
* [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] |
* [https://docs.microsoft.com/en-us/windows-hardware/drivers/acpi/winacpi-osi How to Identify the Windows Version in ACPI by Using _OSI] |
||
+ | * [https://man.archlinux.org/man/dracut.conf.5 How to override ACPI tables with dracut] |
||
+ | |||
+ | {{TranslationStatus|DSDT|2024-09-07|815413}} |
2024年9月7日 (土) 19:29時点における最新版
関連記事
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' で結果が得られるはずです。
自分で再コンパイルする
この取り組みにおける最良のリソースは、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
を試してみるとよいでしょう。エラーや警告が発生しなければ、問題なく実行できます。
修正済みのコードを使う
カスタム DSDT を使う方法は2つあります:
- ブートローダーによってロードされる CPIO アーカイブを作成する
- カーネルに組み入れてコンパイルする
mkinitcpio の acpi_override フックを使用する
mkinitcpio は acpi_override
フックを提供しており、これは /usr/initcpio/acpi_override/
および /etc/initcpio/acpi_override/
にあるすべての .aml ファイルを取得し、それらを早期に解凍された CPIO アーカイブとして /kernel/firmware/acpi/
内に配置します。これにより、別途 CPIO アーカイブを手動で作成したり、ブートローダーの設定を変更したりする必要がなくなります。mkinitcpio が非圧縮 CPIO アーカイブをメインの initramfs イメージと一緒に1つのファイルにパッキングするからです。
まず、/etc/initcpio/acpi_override
ディレクトリを作成し、必要な .aml ファイルをすべてそこにコピーします。例:
# mkdir /etc/initcpio/acpi_override # cp dsdt.aml /etc/initcpio/acpi_override/
次に、/etc/mkinitcpio.conf
の HOOKS
配列に acpi_override
を追加します:
/etc/mkinitcpio.conf
HOOKS=(... acpi_override)
最後に、Initramfs を再生成 し、再起動します。
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.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
) の絶対パスを指定してください。
GRUB での AML の使用
GRUB を使用すると、さらに簡単な方法を使用できます。上記で作成した .aml ファイルをブート パーティションにコピーします:
# cp dsdt_patch.aml /boot
次に、GRUB 設定に次の行を追加します:
acpi /dsdt_patch.aml
たとえば、これを /etc/grub.d/40_custom
に追加します。後で GRUB 設定を生成することを忘れないでください。
dracut で AML を使用する
Dracut を使用している場合、上記で作成した .aml ファイルを定義された場所にコピーするだけで済みます。対応する設定ファイル /etc/dracut.conf.d/acpi-fix.conf
を作成する必要があります:
acpi_override="yes" acpi_table_dir="/usr/local/lib/firmware/acpi"
オーバーライドが成功したか確認する
オーバーライドが成功したことを確認するメッセージを探します。例えば次のようなものです:
# 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)