Thinkpad X1 Carbon 第6世代+Ubuntu18.04でスリープが正常に動作しない問題の解決手順

公開日:2018/05/20 更新日:2018/05/20
Thinkpad X1 Carbon 第6世代+Ubuntu18.04でスリープが正常に動作しない問題の解決手順のサムネイル

はじめに

Thinkpad X1 Carbon 第6世代にUbuntu18.04をインストールしましたが、画面を閉じてもスリープ状態(もしくはサスペンド状態)になっておらず電池が急速に減ってしまいました。また、画面を閉じている間でも本体が結構な熱を持っていました。調べたところThinkpad X1 Carbon 第6世代ではこれまでサポートされていた電源管理モードであるS3がサポートされなくなり、それによりUbuntuではきちんとスリープできなくなっているようです。 ネットを調べると同様の報告が多く挙がっており、大変ありがたいことにその解決策も詳しく公開されていました。そしてその解決策を実施したところ現在では問題なくスリープが動作しています。

なお、スリープ復帰後にトラックポイントとタッチパッドが動作しなくなる問題がありましたが、こちらも見事に解決されました。以降に実際に実施した手順を載せます。なお、全て自己責任でお願いします。もしかしたら初期化が必要になる可能性もあるため、Ubuntuをインストールして環境整備する前に行ったほうがいいかもしれません。私は色々なアプリをインストールしたり設定変更したりと環境を整備済の状態で行ったのでちょっとドキドキしましたが、幸い無事に解決できました。

## 2018/7/7 追記 以降の方法よりもはるかに簡単な方法がLenovoフォーラムで回答されていましたので追記します。 以下のように、/etc/default/grubを修正するだけで見事にスリープが正常に動作します。具体的には、/etc/default/grubの中のGRUB_CMDLINE_LINUX_DEFAULTacpi.ec_no_wakeup=1を追記するだけです。8時間放置してバッテリーが10%減るか減らないかぐらいまでになります。ただし、副作用として、ラップトップを開いただけではスリープから復帰せず、電源ボタンを押す必要があります。逆に言えばそれだけです。

(変更前) 
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" 

(変更後) 
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash acpi.ec_no_wakeup=1"

実施した環境と前提

私の環境は以下のようになります。以下の環境でないと有効でないというわけではなく、むしろ以下の環境でも有効でした。

  • Thinkpad X1 Carbon 第6世代
  • Windows10 と Ubuntu18.04 でデュアルブート環境構築済(rEFInd を使用)
  • Ubuntu18.04のカーネルverは4.15

参考サイト

色々なサイトを見ましたが、一番元となる情報を掲載しているのは以下の一番上のサイトのようです。今回の作業で必要となるパッチファイルもこちらのサイトにあるものを使わせて頂きました。

A good night's sleep for the Lenovo X1 Carbon Gen6 - Delta Xi. Ubuntu 18.04 Initial Setup - Plum's Blog Troubles with X1 Carbon 2018 (X1C6) TouchPad and TrackPoint under Linux - Lenovo Community

手順概要

基本的には参考サイトと同じ手順になりますが、いくつか注意点あったのでそちらも含めて載せます。なお、以降で色々な単語が出てきますが、これらをすべて理解しなくとも手順を追えば実施できると思います。もちろんきっちり理解することが理想ですが、私のように取り急ぎ望みの動作をしてくれればいいという方はそれでも良いと思います。なお、以降ではターミナル上での作業になり、基本的なLinuxコマンドについては理解していることが前提となります。

以下の作業の目的は、ACPI(Wikipedia参照)で定義されているモードの1つである、S3を有効化することです。S3を有効化することで、従来通りのスリープを動作させることができるようになります。なお、2018年発売のThinkpad の中ではThinkpad X1 CarbonとYogaだけがS3をサポートしてないようで(代わりにModen Standby(S0i3)をサポートとのこと)、例えば T480s などはサポートしているようです。 以下が大まかな作業の流れになります。ステップ自体は多くなっていますが、各作業自体はすぐ終わるため思っていたよりも楽だと思います。

  • 1.BIOSでThunderbold3のAssist modeを有効化
  • 2. S3のサポート有無確認
  • 3. 必要なパッケージをインストール
  • 4. ACPI DSDTテーブルをダンプ
  • 5. DSDTテーブルをデコンパイル
  • 6. パッチをあてる
  • 7. DSDTテーブルを再度コンパイル
  • 8. 上書き用のACPIファイルを作成
  • 9. /boot/grub/grub.cfg を修正
  • 10. GRUB修正
  • 11. TLPインストール

解決手順

BIOSでThunderbold3のAssist modeを有効化

BIOS画面で、Thunderbolt3のメニューからAssist modeをEnabledに変更します。また、Securityの中にあるSecure BootDisabledにしておく必要があります。

S3のサポート有無確認

dmesgコマンドで、サポートしているACPIのモードを確認します。

$ dmesg | grep -i acpi | grep supports
[ 0.112419] ACPI: (supports S0 S4 S5)
[ 0.181924] acpi PNP0A08:00: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI]

上記を見てわかるように、ACPI: (supports S0 S4 S5)となっており、S3が含まれていないことが分かります。ここにS3を追加するための作業になります。

必要パッケージのをインストール

以降の作業で必要となるiaslcpioaptでインストールします。 以下では最初にまずupdateしています。

$ sudo apt update
$ sudo apt install iasl
$ sudo apt install cpio

ちなみに私の環境ではcpioはインストール済でした。

ACPI DSDTテーブルをダンプ

以下コマンドでDSDTテーブルの内容をダンプします。dsdt.amlというファイルが現在のディレクトリに作成されます。私はホームディレクトリで作業していたため、ホームディレクトリにdsdt.amlが作成されました。

$ sudo cat /sys/firmware/acpi/tables/DSDT > dsdt.aml

DSDTテーブルをデコンパイル

iaslコマンドを使ってdsdt.amlをデコンパイルします。私の環境では実行結果として以下のように表示されました。

$ iasl -d dsdt.aml

Intel ACPI Component Architecture
ASL+ Optimizing Compiler/Disassembler version 20180105
Copyright (c) 2000 - 2018 Intel Corporation

Input file dsdt.aml, Length 0x26183 (156035) bytes
ACPI: DSDT 0x0000000000000000 026183 (v02 LENOVO SKL 00000000 INTL 20160527)
Pass 1 parse of [DSDT]
Pass 2 parse of [DSDT]
Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)

Parsing completed
Disassembly completed
ASL Output: dsdt.dsl - 1077991 bytes

パッチをあてる

冒頭に載せた参考サイトに置いてあるパッチファイル( https://delta-xi.net/download/X1C6_S3_DSDT.patch )をダウンロードし、このパッチファイルをdsdt.dslがあるディレクトリと同じディレクトリに置きます。 その上で以下のようにpatchコマンドを実行します。X1C6_S3_DSDT.patchがダウンロードしたパッチファイルです。

$ patch --verbose < X1C6_S3_DSDT.patch
Hmm... Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|--- dsdt.dsl 2018-03-03 14:47:12.279105691 +0100
|+++ dsdt.dsl 2018-03-03 14:26:30.606427931 +0100
--------------------------
patching file dsdt.dsl
Using Plan A...
Hunk #1 succeeded at 18.
Hunk #2 succeeded at 39.
Hunk #3 succeeded at 66.
Hunk #4 succeeded at 159.
Hunk #5 succeeded at 177.
Hunk #6 succeeded at 195 with fuzz 1.
Hunk #7 FAILED at 351.
Hunk #8 succeeded at 13765 (offset 5 lines).
Hunk #9 succeeded at 27515 (offset 21 lines).
Hunk #10 succeeded at 34765 (offset 28 lines).
1 out of 10 hunks FAILED -- saving rejects to file dsdt.dsl.rej
done

上記を見ると、Hunk #7 FAILED at 351.と表示されており、#Hunk 7が失敗しているのが分かります。環境によっては#Hunk 6が失敗する場合もあるようです。これを修正するために、以下のようにエディタでdsdt.dslを開いて修正します。以下ではviエディタを使用しています。

$ sudo vi dsdt.dsl

dsdt.dslの354行目と356行目に、Oneという記述があると思います。この2つのOneを削除 or コメント化します。 私は以下のようにコメント化しました。

(・・・上省略・・・)
 Name (SS1, 0x00)
    Name (SS2, 0x00)
    Name (SS3, One)
    /* One */
    Name (SS4, One)
    /* One */
    OperationRegion (GNVS, SystemMemory, 0x4FF4E000, 0x0771)
    Field (GNVS, AnyAcc, Lock, Preserve)
(・・・下省略・・・)

また、この編集時にdsdt.dslの21行目にあるDefinitionBlockという部分を確認します。 そこに0x00000001という番号になっていることを確認してください。これが0x0000000のままだと、 以降の作業は反映されないようです。具体的には以下のようになっています。

/*
* Intel ACPI Component Architecture
* AML/ASL+ Disassembler version 20180105 (64-bit version)
* Copyright (c) 2000 - 2018 Intel Corporation
*
* Disassembling to symbolic ASL+ operators
*
* Disassembly of dsdt.aml, Fri May 18 22:30:19 2018
*
* Original Table Header:
* Signature "DSDT"
* Length 0x00026183 (156035)
* Revision 0x02
* Checksum 0xD7
* OEM ID "LENOVO"
* OEM Table ID "SKL "
* OEM Revision 0x00000000 (0)
* Compiler ID "INTL"
* Compiler Version 0x20160527 (538314023)
*/
DefinitionBlock ("", "DSDT", 2, "LENOVO", "SKL ", 0x00000001) /* 0x00000001 なっていることを確認*/

DSDTテーブルを再度コンパイル

iaslコマンドで再度コンパイルします。

$ iasl -ve -tc dsdt.dsl
Intel ACPI Component Architecture
ASL+ Optimizing Compiler/Disassembler version 20180105
Copyright (c) 2000 - 2018 Intel Corporation

ASL Input: dsdt.dsl - 34769 lines, 1075446 bytes, 15321 keywords
AML Output: dsdt.aml - 144267 bytes, 2876 named objects, 12445 executable opcodes
Hex Dump: dsdt.hex - 1352883 bytes

Compilation complete. 0 Errors, 332 Warnings, 116 Remarks, 6298 Optimizations, 46 Constants Folded

0 Errorsとなっておりエラーが出ていないことを確認します。

上書き用のACPIファイルを作成

以下のように適当なディレクトリでacpi_ovverrideというファイルを作成します。以下ではホームディレクトリにfors3というディレクトリを作成しそこに移動して作業しています。最終的にfors3ディレクトリにacpi_overrideというファイルが作成され、これを次のステップで使用します。

$ cd
$ mkdir fors3
$ cd fors3/
$ mkdir -p kernel/firmware/acpi
$ cp ../dsdt.aml kernel/firmware/acpi/
$ find kernel | cpio -H newc --create > acpi_override
284 ブロック

作成したacpi_override/bootにコピーしておきます。

$ sudo cp acpi_override /boot/acpi_override

/boot/grub/grub.cfg を修正

grub.cfgをエディタで修正します。

$ sudo vi /boot/grub/grub.cfg

grub.cfgの中にある、Ubuntuに関する記述を見つけ、そこに追記をします。

(・・・上省略・・・)

menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-59cb91d7-9289-403e-aeb3-8c74320e57b5' {
        recordfail
        load_video
        gfxmode $linux_gfx_mode
        insmod gzio
        if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
        insmod part_gpt
        insmod ext2
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root  59cb91d7-9289-403e-aeb3-8c74320e57b5
        else
          search --no-floppy --fs-uuid --set=root 59cb91d7-9289-403e-aeb3-8c74320e57b5
        fi
        linux   /boot/vmlinuz-4.15.0-20-generic root=UUID=59cb91d7-9289-403e-aeb3-8c74320e57b5 ro  quiet splash psmouse.synaptics_intertouch=1 $vt_handoff
        initrd  /boot/initrd.img-4.15.0-20-generic
        initrd  /boot/acpi_override /boot/initrd.img-4.15.0-20-generic /* ここを追記 */
}
(・・・下省略・・・)

追記した内容は以下です。/boot/acpi_overrideは前のステップで作成済のものです。/boot/initrd.img-4.15.0-20-genericは各自のカーネルバージョンによって異なります。自分のカーネルバージョンは追記前の行にあるinitrd /boot/initrd.img-4.15.0-20-genericをそのままコピーすればOKです。

initrd /boot/acpi_override /boot/initrd.img-4.15.0-20-generic

GRUB修正

/etc/default/grubを修正します。

$ sudo vi /etc/default/grub

以下のようにmem_sleep_default=deepを追記します。

(変更前)
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash psmouse.synaptics_intertouch=1"

(変更後)
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash psmouse.synaptics_intertouch=1 mem_sleep_default=deep"

なお、上記のpsmouse.synaptics_intertouch=1という記述は、デフォルトでは記述がないと思います。これは、Thinkapd X1 Carbonのトラックポイントとタッチパッドを動作させるために私自身が以前追記したものです。もしThinkapd X1 Carbon+Ubuntu18.04 でトラックポイントとタッチパッドが動作しないなどの問題ある場合は、こちらに対策手順まとめています。

以上で主な作業は完了になります。あとは再起動してもう一度dmesgで確認します。見てわかるよおり、S3が追加されています。これでスリープが問題なく動作すると思います。

$ dmesg | grep -i acpi | grep supports
[ 0.113002] ACPI: (supports S0 S3 S4 S5)
[ 0.181816] acpi PNP0A08:00: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI]

また、mem_sleepを表示すると、以下のようになります。

$ cat /sys/power/mem_sleep
[s2idle] deep

TLPのインストール

電源管理用のパッケージであるtlpをインストールしておきます。TLPに電源管理を任せることで電池もより持つようになります。

$ sudo apt install tlp

以上ですべての作業が完了です。

まとめ

今回はじめてThinkpad X1 CarbonにUbuntuを入れてみましたが、やはり色々と問題には遭遇します。ただ、驚くほどたくさんの情報がネット上にあり、対策を思っていたよりも簡単にできるようになっています。もしまた問題が発生するようならば追記します。

関連記事

開発アプリ

nanolog.app

毎日の小さな出来事をなんでも記録して、ログとして残すためのライフログアプリです。