メモリが基板直付けだと、壊れた領域をカーネルから外して使い続けるしかない

Ben Hardill の X1 Carbon はタブが頻繁に落ち、ルートファイルシステムがたびたび読み取り専用になった。memtest86+ を数分走らせると 7919 件のエラーが出たが、メモリは基板直付けで交換できない。結局 memmap で不良アドレスをカーネルから外し、そのまま使い続けることにした。

日本語
コピー
手机翻拍的 Memtest86+ 蓝色界面,右上角写着 Status: Failed! 与 Errors: 7919,下半屏是 Linux memmap 参数列表

オンボード RAM というノート PC のトレンドは、本当に邪悪だ。ましてや供給不足で価格が高騰しているこんな時に。

普段はノート PC を 2 台使い分けている。1 台はプライベート用、もう 1 台は仕事用で、少しでも両者を分けておきたいのと、仕事が終わったら仕事用を「オフィス」に置いて帰れるようにするためだ。2021 年に今の仕事用ノート PCを手に入れたときのことはブログに書いた。

この Lenovo X1 Carbon は絶好調だった。ところが最近、ブラウザのタブが頻繁にクラッシュするようになり、時折ルートファイルシステムが勝手に ReadOnly になってしまう。まったく役に立たない挙動だ。

Oct 15 23:33:35 razor-crest kernel: BTRFS warning (device dm-0): csum failed root 257 ino 166754 off 5859786752 csum 0x31019647 expected csum 0x6d009929 mirror 1
Oct 15 23:33:35 razor-crest kernel: BTRFS error (device dm-0): bdev /dev/mapper/luks-571c7357-a343-49f3-993c-167c8c5dcec6 errs: wr 0, rd 0, flush 0, corrupt 3856936704, gen 0

この不具合を見て RAM のエラーではないかと思い、memtest86+のブートイメージを Ventoy の USB メモリに追加して起動してみた。

Memtest86+

このツールは最小限の OS を起動し、物理メモリのあらゆるアドレスにさまざまなパターンを書き込んでは読み戻す。読み戻した値が書き込んだ値と一致しなければ、そこに問題がある。

放っておけば複数回パスを繰り返す。間欠的にしか現れないエラーもあるからだ。だが今回は、ほぼ即座に大量のエラーが出た。

以前ならこれは簡単に直せた。出力を見ればどの DIMM が故障しているか特定できたし、最悪でも 1 枚抜いて再度テストを回せば二分探索で絞り込めた。特定できたら交換用の DIMM を注文する(ついでにアップグレードするのもいい)だけで済んだ。

ところが、より薄いノート PC を追求するあまり(DIMM ソケットは奥行きを約 6mm 増やす)、そしておそらくは故障したら新しいノート PC を買うしかないようにするという皮算用から、今やほとんどのノート PC では RAM がマザーボードに直接はんだ付けされている(FrameWork などは例外だ)。BGA チップの交換に熟練していない限り、交換は現実的な選択肢ではない。

5 年での減価償却と技術の進歩を考えれば、新しいノート PC を探す頃合いなのは確かだ。それでも、この Lenovo X1 Carbon を何とか動かし続けられないか見てみたい。まだ十分に使えるマシンだし、プライベート用に使っているさらに古い Dell XPS 13 の代わりにもなる。

交換の話は後で書く。

Memmap

新しいノート PC が届くのを待つ間に、もう少し安定させられないか試してみることにした。

少し調べてみると、壊れたセクタを避けるように Linux カーネルへ渡せるオプションが 2 つ見つかった。

  • badram
  • memmap

badram はツリー外のパッチで、通常は Debian/Ubuntu 系のディストリビューションでしか配布されていないらしい。このマシンは Fedora なので使えない。

memmap はカーネルのコア機能なので、Fedora でも使えるはずだ。カーネルコマンドラインに length$offset 形式でメモリアドレスと長さのリストを渡す必要がある。

Memtest86+は正しい形式(badram と memmap の両方)で出力でき、ファイルに保存もできるのだが、Ventoy の USB メモリに入れた iso のイメージではうまく動かせなかった。仕方なく画面を写真に撮ることにした。

ノート PC の画面を撮影した Memtest86+のエラー出力

これを手で書き写す作業が待っていた。なかなか「楽しかった」。

カーネルコマンドライン引数の追加についてのドキュメントはどれも、/etc/default/grub ファイルを編集して GRUB_CMDLINE_LINUX のエントリに値を追加し、grub2-mkconfig -o /boot/grub2/grub.cfg を実行しろと書いている。

GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="rd.luks.uuid=luks-571c7357-a343-49f3-993c-167c8c5dcec6 rhgb quiet memmap=\$memmap_val memmap=0x30$0x3fe90140,0x48$0x3fe90b08,0x48$0x3fe90ba8,0x48$0x3fe916a8,0xf0$0x3fe91c00,0x90$0x3fe92560,0xf0$0x3fe92f00,0x50$0x3fe93200,0x90$0x3fe93260,0xf0$0x3fe93800,0xf0$0x3fed4300,0x70$0x3fed4900,0x70$0x3fed4980,0xf0$0x3fed5400,0xf0$0x3fed5e00,0xf0$0x3fed6700,0xf0$0x3fed6d00,0xf0$0x3fed7000,0x30$0x3fed7a00,0xb0$0x3fed7a40"
GRUB_DISABLE_RECOVERY="true"
GRUB_ENABLE_BLSCFG=true

試してみたが、再起動すると起動に失敗した。

grub の画面までたどり着き、起動しようとしているカーネルコマンドラインを表示すると、memmap エントリ内の $0 が grub2-mkconfig に置き換わっていた。典型的な環境変数の展開だ($0 は通常、実行中のスクリプト名になる)。

似た問題を扱った RedHat のbugを見つけ、値を変数として追加する解決策が載っていた。

# grub2-editenv /boot/grub2/grubenv set memmap_val='0x30\$0x3fe90140,0x48\$0x3fe90b08,0x48\$0x3fe90ba8,0x48\$0x3fe916a8,0xf0\$0x3fe91c00,0x90\$0x3fe92560,0xf0\$0x3fe92f00,0x50\$0x3fe93200,0x90\$0x3fe93260,0xf0\$0x3fe93800,0xf0\$0x3fed4300,0x70\$0x3fed4900,0x70\$0x3fed4980,0xf0\$0x3fed5400,0xf0\$0x3fed5e00,0xf0\$0x3fed6700,0xf0\$0x3fed6d00,0xf0\$0x3fed7000,0x30\$0x3fed7a00,0xb0\$0x3fed7a40'

/etc/default/grub を次のように変更する。

GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="rd.luks.uuid=luks-571c7357-a343-49f3-993c-167c8c5dcec6 rhgb quiet memmap=\$memmap_val"
GRUB_DISABLE_RECOVERY="true"
GRUB_ENABLE_BLSCFG=true

そしてもう一度 grub2-mkconfig -o /boot/grub2/grub.cfg を実行する。

今度はちゃんと起動し、正しい値が /proc/cmdline で確認できた。

BOOT_IMAGE=(hd0,gpt2)/vmlinuz-7.2.11-200.fc44.x86_64 root=UUID=869b183b-b858-40e5-8da7-e923dd367c2a ro rootflags=subvol=root rd.luks.uuid=luks-571c7357-a343-49f3-993c-167c8c5dcec6 rhgb quiet memmap=0x30$0x3fe90140,0x48$0x3fe90b08,0x48$0x3fe90ba8,0x48$0x3fe916a8,0xf0$0x3fe91c00,0x90$0x3fe92560,0xf0$0x3fe92f00,0x50$0x3fe93200,0x90$0x3fe93260,0xf0$0x3fe93800,0xf0$0x3fed4300,0x70$0x3fed4900,0x70$0x3fed4980,0xf0$0x3fed5400,0xf0$0x3fed5e00,0xf0$0x3fed6700,0xf0$0x3fed6d00,0xf0$0x3fed7000,0x30$0x3fed7a00,0xb0$0x3fed7a40

memmap の値を USB メモリ上のテキストファイルに保存しておいたので、完全に再インストールすることになっても再適用できる。新しいノート PC が届くまで、できればもう少し長く、これで動き続けるはずだ。

次の作業は、必要なものすべてをバックアップしたことを確認し、それから btrfs check --fix を実行してファイルシステムのメタデータを整理できるか試すことだ。

出典: blog.hardill.me.uk← ホームへ戻る