2023/01/01(Sun)BIOS更新で文鎮化してしまったThinkPad X13 Gen2を自力で直したメモ

2023/01/01 1:04 Hardware::ThinkPad
ThinkPadユーザならお馴染みのLenovo Vantageから、「BIOSとIntel MEの更新があるので、今すぐ適用してね!」とポップアップが出たため実行したところ、フラッシュが終わったと思しき後から起動しなくなりました。
それを直した時のメモ。


環境メモ

マシン
ThinkPad X13 Gen2
Type Number
20WK-CTO1WW 2021/06製
文鎮化した日
2022/12/28
文鎮化時点のBIOSバージョン
BIOS 1.50 (N35ET50W), ECP 1.41 (N35HT41W)を適用しようとした模様
文鎮化時点のIntel MEバージョン
15.0.42.2235を適用しようとした模様
文鎮化直前の状態としては、
  • Lenovo Vantageで、BIOSアップデートとIntel MEアップデートのみがリストされた状態になっていた
  • この時、バッテリは8割程度充電済みで、社外製60WのUSB-Cアダプタで充電しながら行っていた
  • アップデート適用を実施して、Windowsがリブートしたところ、BIOS書き込みはDOS画面で順調に進行していたものの、最後に成功のメッセージが出る部分は目視できておらず、気がついたときには「電源LEDが通常の点灯状態で、LCDバックライトが付いたり消えたりしている」状況だった
  • 電源を投入し直したり、純正の電源アダプタを繋げても、緊急リセットピンホールを10秒長押ししても状況が変わらず、BIOS POST画面が出ない
  • キーボードのバックライトLED、F1,F4,CapsLock,FnLock(Esc)のLEDは一切点灯しない
以上のことから、BIOSもしくはIntel MEのアップデート適用時に問題が起こった可能性が高いと判断した次第です。

通常ならメーカーにセンドバックして修理を依頼するしかない、という状況ですよね。
しかし購入から1年ちょっと経過しており、延長保証も付けていなかったため*1、なんとか自力で直らないものか、色々やってみることに。

*1 : あまりノートPCを持ち歩かないので物理消耗・故障も起こりづらく、パーツなら大体自力で交換出来るし、まさか、BIOS生焼けするとか思わないし…

修理方法

大まかな修理方法と概算費用をリサーチしたところ
メーカ修理
修理サービス - 引き取り修理の修理概算料金 - Lenovo Support JPによれば、作業費18,920 + 送料3,410 + システムボード部品 57,750~ ≒ 8万円~コース
街のPC修理屋さん
場所にもよるものの、成功報酬で1.5万円とか?
という感じで、まあ安いPC/中古PCなら買い直しも考える位のお値段がするわけですが、そもそもBIOSはEEPROM ICに実装されているので、ROM Programmer (ROM Writer)と呼ばれる機械を使えば、外(≒別のPC)から強制的に書き換えることが出来ます。街の修理屋さんがやっていることは十中八九コレでしょう。*2

*2 : 中にはメーカに部品発注して、交換工賃をメーカよりお安くやってるだけの所もあるかもしれないけど

EEPROMの特定とROM Programmerの選定

ROM Programmerを選ぶに辺り、EEPROMの特性にあった機器を選定するのはマストです。
まずはPCを分解し、EEPROMを見つけることから始めます。
以下、毎度書くのは省略しますが、基盤を弄るときは電源のUSB-Cケーブル、内蔵バッテリ、CMOS電池を必ず抜いて作業します。

裏蓋を開けるとCPUからあまり遠くない位置に、8pinで大きめのチップがあるはず…ということで探していきますが、保護テープやフィルムの下に隠れていることもあるので、くまなく見つけます。
ThinkPad X13 Gen2 (20WK-CTO1WW)の場合、Winbond社のW25R256JVというチップがCPU横の保護テープ下に隠れていました。

▼全景
x13gen2-01.jpg

▼CPU上部のアップ … 保護テープにヒートシンクが被さっているので一部だけしか見えませんが
x13gen2-02.jpg

▼チップ部のアップ … "Winbond 25R256JV"が見えます
x13gen2-03.jpg


さて、このチップ、メーカ情報によれば、3.3V, 256Mbit=32MB, SPI interfaceです。(ググれば更にピンアサインなど、細かいデータシートも出てきます)
旧3桁型番のThinkpad X260でもWinbond社のW25Q128FV等が使われているようだったので、容量の大きな物へとシフトしているのでしょう。

結局は、先人達のblogにも良く登場していたメジャーなKeeYees CH341AというProgrammerを購入することにしたのですが、実は公表されている互換性ガイドにはこの型番が載っていません。
まあ、似た型番があるし、安いのでダメだったらチップ容量だけソフトに手動設定する等して乗り切ればよいやと買ってしまいました。

Amazonで送料込1400円程。Amazon.co.jp発送で12/28に購入し、通常配送では1/1到着予定だったにもかかわらず、12/30に届きました。
▼商品ページ
asin:B07W7RQ53X

他の特性として、電圧が3.3Vだったり、5Vあるいは1.8Vだったり、型番が25xx系と24xx系などあるので、間違った電圧をかけてチップ自体を破壊しないようには気を付けましょう。

CH341Aについて

使い方は至ってシンプルで、probeを8pinのEEPROMに配線した後、USBメモリのような本体と繋ぎ、正常動作するWindows PCにUSB-Aコネクタを差し込むだけです。ただ、万人が扱えるシロモノでないのは確かですけど。

デバイスドライバは、Amazon購入後に送られてくるショップからのコメントに添付されたPDFに含まれています。が、GitHubのそれらしいリポジトリにも入っているので、私はこれを使用しました。*3
上のzipには、説明書の他、USBデバイスのドライバ、ソフトウェアが含まれています。
ただ、信用のおけないアプリだったので、これらのツールは全てVM環境内にインストールし、USB機器をVMゲストへbypassして実施しました。

インストール自体はOKだったものの、CH341A添付のソフトには、W25R256JV用の設定が無かったため、別のGitHubに公開されているAsProgrammerを使ってみることに。v2.3.0a時点で、こちらには設定がありました。

▼CH341A
x13gen2-04.png

x13gen2-05.png


▼AsProgrammer
x13gen2-06.png

x13gen2-07.png


.oOO( サイズとページが埋め込まれるだけっぽいので、ここの値さえ分かればリストに無いチップでもProgramできるのでは…? )
x13gen2-08.png

ちなみにAsProgrammerは日本語表記もあるものの、部分的にロシア語に化ける部分もあったので、割り切って英語で使う方が良いかも。

*3 : ブラウザでのダウンロード時に、マルウェア警告が出ましたが、まあ…^^;

チップへの接続方法

CH341には、接点付きのクリップが付属しているので、これを使ってEEPROMチップを挟むようにすれば良いのですが、X13 Gen2の場合はCPU付近の絶縁シートの下に埋まっているので、ヒートシンク(+CPUファン)とシートの両方を一旦取り外す必要がありました。

完全に露出するとこんな感じ。
x13gen2-09.jpg

よく見るとW25R256JVチップが上下2つに並んでいるのですが、シルク印刷より「上側の方がBIOS」で、「左上から左下に5-8pin」「右上から右下に4-1pin」が配置されていることが分かります。
下側のチップはリカバリ用なのか、別の用途に使っているのか不明ですし、pinが殆ど隠れているので、ROM Programmerでどうこうするのは難しいでしょう…
ということで、間違えないように上側をクリップで挟んでみます。1.27mmピッチなのでなかなか難しい…
x13gen2-10.jpg

クリップは割と堅いバネが入っているので広げるのに力が要りますし、下手をするとクリップの脆い端子やEEPROMの外装を割ってしまう可能性があるので、ここは本当に慎重に……。

とりあえずReadをやってみたらどうなるか試してみたところ、全部0xFFとなりました。
大したチェック無しにデータをチップからローレベルに読み込んでいるだけなので、この手の表示になったら正しく読めていないっぽいです。(probeを一切接続していない状態でReadしても同様)
x13gen2-11.png

x13gen2-12.png


理由を考えてみたところ、クリップは横方向に挟んでいるため、X13 Gen2のようにチップの高さが無く、チップの足が基盤に沿って水平に伸びている場合に必要な上下方向の圧力が無く、導通状態を維持できないようです。
(4pinがGNDとわかっているので、テスタで適当なネジ穴辺りのGNDと導通チェックしながらクリップを動かしてみたところ、たまにショートしたので、上下左右ともかなりシビアな位置調整が求められることは間違いないです。)

2023/1/1 14:00 ICパッケージについての追記

twitterで教えて頂いたのですが、CH341Aに付属のクリップはSOP(Small Outline Package)というICの横からガルウィング形のリードが出ているものを挟み込む物で、W25R256JVのようなWSON(Very-Very thin Small Outline Non-leaded package)のようなリード無しで電極パッドのみのIC向けでは無いとのことです。@nvsoftsさんありがとうございます。
なのでX13 Gen2のBIOS修理には、基板に半田付けか、基板から部品を外して変換アダプタ噛ませるか、いずれにせよ半田ごて必須ということになりそうですね。


なので、諦めて半田付けすることに。
適当な電線を8本用意し、予備ハンダをしておいてから、一番細いコテ先に切り替えてEEPROMに半田付けします。隣のゴム製ケーブルガイドを焦がさないように注意。横着して外さずにやりましたが、取った方が安全です。
x13gen2-13.jpg


反対側は、CH341Aに付属のブランクボードに半田付けして差し込むだけです。お好きな方法で良いです。
全景はこんな感じ。半田付けの際にフラックスが飛び散らないよう、カレンダー等の厚紙を被せて作業しています。
x13gen2-14.jpg


オリジナルのバックアップ

接続状態を万全にした上で、Readを再実施した(ツールバーの□→ボタン)ところ、0xFF以外の意味のある文字が見えました。
他の方の作業スクショとも比べましたが、Eyecatcherが必ずコレというものではないようなので、PHCMから始まっていないからといって失敗ではないと思います。
x13gen2-15.png


もっとスクロールしていくと、テキスト部と思わしき可読領域が出てきたので、まあ正しく読めているという確信が持てます。
その状態で必ずVerify(ツールバーの□=ボタン)しておきましょう。5分程度かかりますが、完全に壊してしまったときのラストリゾートになります。先ほども書いたように、1度読んだからといって、どこのビットも化けていない保証はないので、2回読んで完全に同じであることを確認してやっと信頼して良いと思っておいた方が良いです。
作業を続ける前に、このファイルは複数箇所に保管しておくことをオススメします。
x13gen2-16.png


ファームウェアの解析

取り出したデータを目で読んでいくのは大変なので、UEFITool NEを使って中身の構成を確認してみます。
UEFIToolは色々亜種があり、
無印のUEFI Tool
編集できるが、サポートしている形式が限定的
UEFITool NE(New Engine)
編集できないが、サポートしている形式が無印より多い
とのことなので、NEの方+適当なバイナリエディタ(Bzなど)を使うことにします。

で表示してみるとこのようになります。
x13gen2-17.png


各セクションを眺めながらOffsetを確認していったところ、32MBの内訳は
0x00000000~ (size=0x1000, 4kB) Descriptor region
後続regionのoffsetやR/W, IC特性などを保管する共通域
0x00001000~ (size=0x40000, 256kB) Padding
良く分からないけど何か入っている
0x00041000~ (size=0x2000, 8kB) GbE region
内蔵Gigabit EtherのMACアドレスが入っている。これが実際と一致しているならばイメージの破壊がないと見ても良さそう
0x00043000~ (size=0xfbd000, 約15.7MB) ME region
Intel MEのFirmware+Data領域っぽい
0x01000000~ (size=0x100000, 16MB) BIOS region
BIOS/UEFI領域っぽい
Lenovoのサイトから適当にLinux用のzipをダウンロードしてくると、BIOSとECP(Embeded Controller Program)の2つのfirmware.binが入っており、片方が16MBきっかり、もう片方が750kb位の中途半端なサイズであり、BIOS regionと同じようなツリー内容が見えたので、BIOS region=firmware.binと推定できます。

ちなみに色が付いている行は、BootGuard markingsということなので、適当に改変すると改変を検知されてブートが中断するような領域っぽいです。
他にもUEFI自体の設定値を保管している箇所もあるので、そういった部分は差分になって然りですが、BootGuard領域に差分があれば、確実に生焼けと断定出来るのではないかと。

ダウンロードデータとの比較

UEFIToolを使って、吸い出したファイルから後半16MBのBIOS regionと、firmware.binから16MBピッタリになるUEFI file(6C60EE00-C316-...の部分)を適当なファイルに切り出します。
x13gen2-18.png


次に、比較ツールを使ってバイナリコンペアをします。私は手持ちのBeyond Compareを使用しましたが、まあフリーウェアでもWinDiffとかで出来るんじゃないですかね。
x13gen2-19.png


しかしながら、上記結果を見る限り、BootGuard領域が開始するB23E7388-9953-45C7-9201-0473DDE5487AのOffset=0x00340000以前にしか差分がないので、Microcodeが壊れているわけでは無さそうという結論になりました。

What's next?

ここまでに分かったことは
・EEPROMチップ自体は壊れていない
・焼かれているBIOSはほぼ最新2.50になっていて、Microcode部分は完全一致する(生焼けではない?)

残っている疑念は
・UEFIのその他の領域が壊れている?
・もしかしたらIntel ME領域が壊れた?(この方の症状と同じ?)

最初にIntel MEの方を疑ったものの、Intel マネージメントエンジン 15.0 ファームウェア 15.0.42.2235を展開して出てくるファイルの中で、UEFIイメージっぽい*.capを開いてみるも、3MBだったり10MBだったり、ME regionそのままという感じではなかったので、こちらは断念。
先に、BIOS regionをベタ埋めしてみる作戦をとってみます。

Write時の罠

バイナリエディタを使って、吸い出したデータの後半16MBをぶった切り、firmware.binの内容を連結して新しいbinファイルを作ってみました。
それをWriteしてみた(ツールバーの□←ボタン)のですが、実はこの操作はちょっと間違っていました。
x13gen2-20.png


書き込んでみた後、一旦ROM Programmerを外し、リード線を残したまま起動を試みたところ、今度は電源すら投入できず悪化。
電源のUSB-Cケーブルを接続すると、Power LEDが3度点滅し、充電回路がアクティブになる(コネクタ近くのLEDがオレンジに)ものの、電源ボタンを押してもファンすら廻らずLCDも消灯のまま。

何度か繰り返すうちに、FnLockが点滅しながら、時折F1とF4のLEDも同時点滅する状況が続き、緊急リセットホールによる強制リセットを繰り返してもこれ以上、状況が変わらなくなってしまいました。
症状をググってみると、T14 Gen3の保守マニュアル等でhitし、この挙動は「メモリの再トレーニング」が進行している場合のシグナルということらしいですが……(何を診断してるんでしょ)
メモリー再トレーニングの検出 (T14 Gen 3 Intel モデルのみ)

メモリーの再トレーニングは、コンピューターのメモリー・モジュールを初期化し、メモリー・モジュールの診断テストを実行するプロセスです。以下のような状況が検出されると、POST 中にメモリーの再トレーニングが行われる場合があります。
  • メモリー・モジュールの交換
  • UEFI BIOS の合計メモリー暗号化設定の変更
  • UEFI BIOS の更新 (メモリー・リファレンス・コード [MRC] の変更)
メモリーの再トレーニングが行われると、画面に進行状況が表示されず、空白になる場合があります。
ESC、F1、および F4 の LED インジケーターが順番に点滅して進行状況を示す場合があります。電源ボタンを押してプロセスを中断しないでください。ロゴ画面が表示されるまで数分間待ちます。
ガンガン強制中断させてしまっていましたけど、X13 Gen2ではメモリが全てオンボードなので、UEFI BIOSの変化に伴ってこのプロセスが動き始めたと考えるのが妥当でしょうかね……。

確かにしばらく放っておくと、またパワーオフに戻り、この現象が再発することは無くなりました。

本当に正しく書けたのか?

そういえば、読むときは慎重にやっていたのに、正しくかけたか確認していなかったので、試しにVerifyしてみることに。

すると、なんと先頭に近いoffset=0x00232000でエラー。
内容を読み込んでみると、この領域は0x00ということになっていました。
x13gen2-21.png


後続の相違も確認したところ、いずれも値が小さくなる方向(0xFF→0x00とか、0xED→0x65とか、0xC0→0x40)に化けており、どうやらEraseせずに書き込むと、ビットが片方向(この場合1→0?)にしか変化せず以前の値とORを取ってしまうような状態になるということが分かってきました。
そういえばすっかり忘れてましたが、通常のBIOSアップデートでもEraseプロセスがあるし、EEPROMの特性的にもページ単位で消去が必要ということなので、このプロセスを怠ったのが諸悪の根源ということに……。

そういえば、AsProgrammerのWriteボタンの端の▼を開くと、Unprotect -> erase -> program -> verifyというメニューがあったことを思い出しました。
この操作を行えば、消去・書き込み・検証を自動的にやってくれるので、基本的にはこちらを使うのが正解です。
x13gen2-22.png


再書き込み

ということで、再度Unprotect -> erase -> program -> verifyを使って書き込んでみると、今度はVerifyで失敗しなくなり、正しい内容が書き込めた模様。
x13gen2-23.png

ただし、その分だけ処理時間は延びます。辛抱強く待つことが大事。

しかし…まだ罠はあった

さすがに何か進展があるだろと期待しつつ電源を入れるも、状況変わらず電源LEDは付かないし、LCDも真っ暗のまま。
さすがにBIOSの故障じゃないのではないかと思いつつ、もう打てる手が無いので、EEPROMから電線を外したところ、これがBINGO!

W25Q256JVのデータシートによれば、このEEPROMは133MHzで動作するらしいので、転送時はゆっくりとデータを書くということもあり影響は無さそうでも、Programmerから外して電線を付けたまま宙ぶらりにしてしまうと、アンテナとしてノイズ源になってしまい、ThinkPadが通常のスピードで読み出した場合に影響を及ぼしていると思われます。


リード線を外した後にバッテリーやCMOSを戻し、USB-Cケーブルを接続したところ、勝手に電源が入り、電源LED点灯、そしてキーボードLEDが軽く全点灯して全消灯!
おぉ、これは通常の起動と同じと思いながら待っていると、30秒程度画面暗転が続いた後、Lenovoロゴが表示され、BIOS Self Healing backup progressing...と表示が始まりました。
x13gen2-24.jpg

え?backup…?今まさにBIOSアップデートが終わりましたみたいな挙動だけど、backupも壊れないかしら……と思いつつ、止める方法も無いので、ただ見守ります(汗)

成功か?……ん…?

しばらく待っていると、次のようなメッセージが表示され停止しました。
x13gen2-25.jpg


どうやらPOSTに失敗した事を検知し、Backupから起動したような事が書いてある。CMOS電池を外しているので、日付が飛んでいたりBad checksumは想定通り。おまけにUEFI保存領域も初期化しているので、Bad CRCもまぁ許容範囲ですね。

ということで、このままF1を押してBIOS Setupに入り、時計やその他の設定を戻した後にSave&Exitを選ぶと、一旦電源がオフに。
再び電源をオンにすると、キーボードLEDが一瞬全点灯、ファンが廻る現象があれど画面は暗転したまま1分ほど経過し、また同じようなメッセージが表示されるものの、前より警告は減った状態で止まりました。
x13gen2-26.jpg


なるほど、少しずつ改善しているみたいだけど、毎回何か診断しているのか、restoreしているのか……うーん。
ここで再度時計を合わせた後も少し画面が付くまでに時間がかかったものの、以下のように上の2行とEscで続行とだけ表示されるようになったので、後はEscでこのメッセージを消去すれば終わり…?
System has self-healed by restoring BIOS from backup.
Please check BIOS version and then update BIOS if needed.

Press Esc to continue.

晴れて成功!

最後のEsc押下後、BIOSからのメッセージが出なくなり、通常通りの時間でWindowsがbootするようになりました。やったね!

固有データの復元は?

UEFIのMain画面を見る限り、S/NやUUID、MACアドレスは保持されたままでした。
x13gen2-27.jpg


MACアドレス部分はGbE regionなので上書きしていないからそのまま残るとして、UUIDやS/Nはもしかしたら飛ぶかもと思っていたものの、値は残ったままです。(残念ながらUUIDは控えていないので、以前と同じかどうかは不明)

今回ThinkPadに載せているOSは、プリインストールのものではないため影響は無いのですが、BIOS regionを上書きしたことによってUEFI内に保管されている(offset=0x0032F11C辺り)のWindowsライセンスキーが吹っ飛んでいました。
▼何も表示されない
C:\Users\Kero>wmic path SoftwareLicensingService get OA3xOriginalProductKey
OA3xOriginalProductKey
(ここに表示されるはずのプロダクトキーが何も表示されない)

Self-healingによりBIOSが復元されたとはいえ、復元する場所はBootGuardの領域直前のEfiSystemNvDataFvGuid\EVSA store以下にLnvActivationVar等が保管されている箇所までは弄らないようなので、ここはオリジナルのまま維持しておくのがベターだったかもです。
x13gen2-28.png


まあしかし、もう半田付けしたくないし、オリジナルの情報を保管している以上、必要になったときはこのデータを読めばライセンスキーは困らないので、良いことにします。

参考文献

皆様ありがとうございます。
ちょうべいのThinkPad BIOS関連記事(まとめ) | ちょうべいのThinkPad
ROM Programmerの使い方や、部品の特定、書き換え箇所の勘所など、一番参考にさせて頂きました
UEFI BIOS改造の予備知識 - ふらっと 気の向くままに
吸い出したチップイメージをどう解釈するかについて詳細にまとめられています
CH341A programmer用ツール「AsProgrammer」を試してみました: 猫にコ・ン・バ・ン・ワ
AsProgrammerの基本的な使い方など
PCのUEFI BIOS NVRAM(設定情報) 調査メモ | DXR165の備忘録
EEPROMの特性などについて勉強……
UEFI/BIOSの復旧 – 電子工作
稼働機のバックアップやデータを参考に出来ない状況で、UEFIToolとFirmwareからどうやって復元するか参考にしました
【半導体のパッケージの種類】どのパッケージがどの形を表すの?
半導体の形状の違いについて、非常に分かりやすい図解とともに紹介されています