[心得] Windows禁用出問題的記憶體區段
本篇關鍵字:Bit flipping、PFNs、badram、defective memory、WHEA
大概是聖誕節前後吧,手邊的筆電在看YT時開始跳出分頁崩潰錯誤,時好時壞。
到了1月初,情況甚至變成BSOD,錯誤碼有0x0000001a(MEMORY_MANAGEMENT)、
0x0000003b(SYSTEM_SERVICE_EXCEPTION)、0x00000139(KERNEL_SECURITY_CHECK_FAILURE)
一開始我還沒想透是怎麼一回事,還想說是不是哪個零日漏洞被開採而我中獎了。
直到我順手讀了火狐的錯誤報告,看到這一行:
Possible bit flips max confidence | 92%
阿靠,位元翻轉,這下八九不離十是記憶體的包了。直接上記憶體檢查。
Memtest86+ v7.00 | Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz
CLK/Temp: 1800MHz 39/39°C | Pass 2%
L1 Cache: 32KB 93.8 GB/s | Test 48% ##################
L2 Cache: 256KB 38 GB/s | Test #2 [Address test, own address + window]
L3 Cache: 6MB 22.2 GB/s | Testing: 11GB - 12GB [1GB of 11.9GB]
Memory : 11.9GB 10.7 GB/s | Pattern: own address
--------------------------------------------------------------------------------
CPU: 4 Cores 8 Threads SMP: 8T (PAR) | Time: 0:00:16 Status: Failed! \
RAM: 1600Mhz (DDR4-3200) CAS 22-22-22-52 | Pass: 0 Errors: 5
--------------------------------------------------------------------------------
pCPU PASS Test Failing Address Expected Found
---- ---- ---- ------------------------ --------------- ---------------
0 0 2 0000001c1fd5938 (7.03GB) 0000001c1fd5938 0800001c1fd5938
3 0 2 0000001c1fd2af0 (7.03GB) 0000001c1fd2af0 0100001c1fd2af0
3 0 2 0000001c1fd5938 (7.03GB) 0000001c1fd5938 0800001c1fd5938
PS:不要用Windows內建的記憶體檢查,那就只是個拉基,查不出個東西的。
我一開始就是先用內建檢查,查無問題才想到別處去,結果繞了一圈問題還是出在記憶體
好,由上頁畫面可以看到記憶體在3個位址出現高位翻轉的異常。
知道了出包的記憶體位址,怎麼去關閉呢?
估狗了一下,Windows從Vista開始,
就有支援由開機紀錄(BCD)來宣告無效的記憶體分頁的功能。
而從Windows 10 20H2起,微軟改用了硬體錯誤架構(WHEA)來處理這類狀況,
如果記憶體具有ECC糾錯功能,那麼出錯次數超過閥值時,
Windows就會自動將該區塊宣告為禁用。無須人工介入。
但我的筆電沒吃那麼好,所以才要手動自己來。
我用的是舊式的BCD宣告方式,所以跑Win 7/8的老機器也可以參考這篇。
要修改BCD,首先要有Admin權限。
假設你還進得了作業系統,至少是安全模式。打開有權限的CMD,
查詢目前的故障記憶體列表:
bcdedit /enum {badmemory}
正常你會看到列表為空:
RAM Defects
-----------
identifier {badmemory}
只是因為BCD的列表接受的是頁號(PFN),一個頁號對應一個4k分頁,
需要一個一個去作宣告,沒辦法直接宣告一個範圍。好險我估算了一下,
本次出包的記憶體區間大概是0x1c1fd0000 ~ 0x1c1fd7fff,就8個pages,
還可以用手工列舉。萬一有成千上萬的holes散落在各個實體顆粒上,我可能要想辦法弄
個腳本來key-in。
那怎麼把位址轉換成頁號呢?
首先去頭0,0000001c1fd5938變成1c1fd5938。再去掉低位3位,得到1c1fd5。
0x1c1fd5就是包含該位址的頁號。
把範圍處理成頁號後,回到bcdedit加入:
bcdedit /set {badmemory} 0x1c1fd0 0x1c1fd1 0x1c1fd2 0x1c1fd3 0x1c1fd4
0x1c1fd5 0x1c1fd6 0x1c1fd7
並且啟用禁止訪問故障記憶體:
bcdedit /set {badmemory} badmemoryaccess no
之後再查詢,你會看到:
RAM Defects
-----------
identifier {badmemory}
badmemoryaccess No
badmemorylist 0x1c1fd0
0x1c1fd1
0x1c1fd2
0x1c1fd3
0x1c1fd4
0x1c1fd5
0x1c1fd6
0x1c1fd7
這就完工啦,重啟後Windows將完全無視這些故障的記憶體以保平安。
用RAMMap這類公用程式再去檢查,會直接看不到這段記憶體。
當然這手法只是治標不治本,爭取到時間趕快把問題所在的記憶體模組給換了才是真的。
(手刀下訂一條新記憶體)
畢竟誰也不知道記憶體顆粒狀況會不會進一步惡化,導致故障範圍突破收容列表。
而換完之後記得回到bcdedit,清空列表並還原禁用設定:
bcdedit /deletevalue {badmemory} badmemorylist
打完收工。
最後,我肯定是腦袋去夾到才會買Patriot博帝的記憶體,當時到底在想啥啊我...
我上次看到記憶體檢查噴紅字還是XP時代DDR-400的南亞科欸。
--
https://i.imgur.com/Vk91kSq.gif
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 163.16.242.37 (臺灣)
※ 文章網址: https://www.ptt.cc/bbs/hardware/M.1736396638.A.111.html
※ 編輯: Segal (163.16.242.37 臺灣), 01/09/2025 12:28:56
→
01/09 13:25,
2天前
, 1F
01/09 13:25, 1F
→
01/09 13:26,
2天前
, 2F
01/09 13:26, 2F
→
01/09 13:27,
2天前
, 3F
01/09 13:27, 3F
推
01/09 14:00,
2天前
, 4F
01/09 14:00, 4F
推
01/09 14:57,
1天前
, 5F
01/09 14:57, 5F
推
01/09 22:56,
1天前
, 6F
01/09 22:56, 6F
推
01/10 16:46,
21小時前
, 7F
01/10 16:46, 7F
hardware 近期熱門文章
PTT數位生活區 即時熱門文章