Memtest86+ 是一款免費、開源、獨立的記憶體測試器,適用於 x86 和 x86-64 架構計算機。它提供了比 BIOS 記憶體測試更徹底的記憶體檢查。
它還能夠存取幾乎所有電腦內存,不受作業系統使用內存的限制,也不依賴任何底層軟體(例如 UEFI 庫)。
Memtest86+ 可以直接由 PC BIOS(傳統或 UEFI)載入和運行,也可以透過支援 Linux 16 位元、32 位元、64 位元或 EFI 切換啟動協定的中間啟動載入程式來載入和運行。它應該適用於任何 Pentium 等級或更高版本的 32 位元或 64 位元 CPU。
二進位版本(穩定版本和夜間開發版本)可在 memtest.org 上取得。
Memtest86+ v6.00 是基於 PCMemTest,它是早期 Memtest86+ v5 的分支和重寫,而後者又是 MemTest-86 的分支。 PCMemTest 重寫的目的是:
在創建 PCMemTest 的過程中,Memtest86+ v5 的一些並非測試系統記憶體嚴格需要的功能被刪除。特別是,沒有嘗試測量快取和主記憶體速度,或識別和報告 DRAM 類型。這些功能在 Memtest86+ v6.0 中重新添加和擴展,以創建一個統一的、功能齊全的版本。
Memtest86+ 是根據 GNU 通用公共授權版本 2 (GPLv2) 的條款發布的。除 GPL 的規定外,私人或商業使用沒有任何限制。有關詳細信息,請參閱許可證文件。
建置僅在 Linux 系統上進行了測試,但應該可以在使用 GNU 工具鏈和 ELF 檔案格式的任何系統上進行。所需的工具有:
若要建立 32 位元映像,請將目錄變更為build32
目錄並輸入make
。結果是一個memtest.bin
二進位映像文件,可以透過傳統 BIOS(軟碟模式)或透過使用 Linux 16 位元啟動協定的中間引導程式直接啟動,以及一個可以直接啟動的memtest.efi
二進位映像檔透過32 位元UEFI BIOS。任一映像都可以由中間開機載入程式使用 Linux 32 位元或 32 位元 EFI 切換引導協定來引導。
若要建立 64 位元映像,請將目錄變更為build64
目錄並輸入make
。結果是一個memtest.bin
二進位映像文件,可以透過傳統 BIOS(軟碟模式)或透過使用 Linux 16 位元啟動協定的中間引導程式直接啟動,以及一個可以直接啟動的memtest.efi
二進位映像檔透過64 位元UEFI BIOS。任一映像都可以由中間開機載入程式使用 Linux 32 位元、64 位元或 64 位元 EFI 切換引導協定來引導。
無論哪種情況,要建立可用於建立可啟動 CD、DVD 或 USB 隨身碟的 ISO 映像,請鍵入make iso
,結果是memtest.iso
ISO 映像檔。然後可以將其直接寫入空白 CD 或 DVD,或 USB 隨身碟,然後可以透過傳統或 UEFI PC BIOS 直接啟動。
請注意,寫入 USB 隨身碟時,必須使用dd
命令或使用提供相同功能的公用程式將 ISO 映像直接寫入(「轉儲」)到原始裝置。
使用中間引導程式時, memtest.bin
檔案或memtest.efi
檔案應儲存在引導程式可以存取的磁碟分割區中,並且引導程式設定應更新為從該檔案引導,就像它是 Linux 核心一樣沒有初始RAM 磁碟。可以識別多個引導命令列選項,如下所述。如果使用 16 位元啟動協議,Memtest86+ 將使用文字模式 (640x400) 顯示。如果使用 32 位元或 64 位元引導協議,Memtest86+ 將使用文字模式或圖形模式顯示,如引導程式傳遞給它的boot_params
結構中指定的那樣。如果在圖形模式下,提供的幀緩衝區必須至少為 640x400 像素;如果更大,顯示將居中。如果系統以 UEFI 模式啟動,則必須使用圖形模式。
出於測試目的,也可以選擇建立使用 GRUB 作為中間開機載入程式的 ISO 映像。詳細資訊請參閱build32
或build64
目錄中的Makefile
。 ISO 映像既可以是舊版,也可以是 UEFI 可開機的,因此您需要在建置系統上安裝用於舊版和 EFI 開機的 GRUB 模組(例如,在 Debian 上,所需的 GRUB 模組位於套件grub-pc-bin
、 grub-efi-ia32-bin
和grub-efi-amd64-bin
)。您可能需要調整 Makefile 中的某些路徑和檔案名稱以符合系統上的命名。
grub
目錄中包含的 GRUB 設定檔可在測試 ISO 上使用,但也可作為如何從 GRUB 引導 Memtest86+ 的範例。
中間引導程式可以將引導命令列傳遞給 Memtest86+。命令列可以包含一個或多個選項,以空格分隔。每個選項都由一個選項名稱組成,後面可以選擇跟一個=
號和一個或多個參數,參數之間用逗號分隔。可識別以下選項:
0x
前綴(例如:0xFEDC9000) Memtest86+ 支援傳統鍵盤介面(使用 I/O 連接埠 0x60 和 0x64)和 USB 鍵盤(使用其自己的 USB 裝置驅動程式)。可以透過啟動命令列選擇其中之一或兩者,如果在命令列上未指定,則預設情況下系統以 UEFI 模式啟動時使用兩者,否則僅使用舊版介面。
較舊的 BIOS 通常支援 USB 傳統鍵盤模擬,這使得 USB 鍵盤就像連接到連接埠 0x60 和 0x64 的傳統鍵盤一樣。通常可以在 BIOS 設定選單中啟用或停用此功能。如果 Memtest86+ 的 USB 裝置驅動程式已啟用,它們將覆蓋此設定並直接存取任何 USB 鍵盤。其缺點是 USB 控制器和裝置驅動程式需要保留一些記憶體供其私人使用,這意味著記憶體測試無法覆蓋這些記憶體。因此,為了最大限度地提高測試覆蓋率,如果支持,請啟用 USB 傳統鍵盤模擬,如果在 UEFI 模式下啟動,請在啟動命令列上新增keyboard=legacy
。
注意:當您在 BIOS 設定中啟用相容性系統模組 (CSM) 時,某些 UEFI BIOS 僅支援 USB 傳統鍵盤模擬。其他人僅在實際以傳統模式啟動時才支持它。
許多 USB 裝置並不完全符合 USB 規範。如果 USB 鍵盤探針掛起或無法偵測到鍵盤,請嘗試「usbinit」引導選項提供的各種解決方法。
注意:Memtest86+ USB 驅動程式目前不支援熱插拔。使用這些時,您的 USB 鍵盤應在執行 Memtest86+ 之前插入,並在整個測試過程中保持插入狀態。
一些二合一機器使用 LCD 面板,該面板本身是縱向模式顯示器,但在連接到鍵盤時安裝在側面。當在圖形模式下使用顯示器時,Memtest86+可以旋轉其顯示器以匹配。根據 LCD 面板的方向,在啟動命令列上新增“screen.rhs-up”或“screen.lhs-up”選項。當在文字模式下使用顯示器時,BIOS 應該會自動處理這個問題。
當以傳統模式啟動時,Memtest86+ 將使用 BIOS 或中間引導程式設定的螢幕解析度。在 UEFI 模式下啟動時,Memtest86+ 通常會選擇包含 640x400 像素顯示器的最小可用螢幕解析度。某些 BIOS 傳回有關可用顯示模式的錯誤訊息,因此您可以透過在引導命令列上新增「screen.mode=」選項來覆寫此資訊。
請注意,使用顯示旋轉時,指定的螢幕解析度適用於未旋轉的顯示。
啟動後,Memtest86+ 將初始化其顯示,然後暫停幾秒鐘以允許使用者配置其操作。如果沒有按下任何按鍵,它將自動開始使用單一 CPU 核心執行所有測試,無限期地繼續,直到使用者重新啟動或停止機器。
在啟動和執行測試時,Memtest86+ 回應以下按鍵:
請注意,當啟用滾動鎖定且滾動區域已滿時,測試會停止。
配置選單允許使用者:
在所有情況下,數字鍵都可以用作功能鍵的替代鍵(1 = F1、2 = F2、...0 = F10)。
錯誤報告模式可以隨時改變,而不會中斷目前的測試序列。無論目前錯誤報告模式為何,都會收集錯誤統計資料(因此切換到錯誤摘要模式將顯示自目前測試序列開始以來累積的統計資料)。 BadRAM 模式僅在處於 BadRAM 模式時才會累積。 Linux memmap 區域僅在處於 memmap 模式時累積。壞頁碼僅在壞頁模式下才會累積。
對所選測試、位址範圍或 CPU 排序模式的任何變更都將啟動新的測試序列並重設錯誤統計資料。
僅錯誤計數模式僅顯示自目前測試序列開始以來發現的錯誤總數。
錯誤摘要模式顯示以下資訊:
單獨的錯誤模式顯示每個錯誤實例的以下資訊:
BadRAM 模式模式會累積並顯示錯誤模式,以便與 Linux BadRAM 功能或 GRUB badram 指令一起使用。行以badram=F1,M1,F2,M2...
M
F,M
F
這些模式表明故障發生在 M 中所有1
位上等於 F 的位址中。這些模式旨在以簡潔的語法捕獲由硬體結構引起的錯誤的常規模式。
BadRAM 模式是增量成長的,而不是根據所有錯誤的概覽來計算。出於多種實際原因,對的數量限制為 20。因此,在特殊情況下,從地址列印模式的輸出中手工製作圖案可能會產生更好的結果。
注意:正如各個測試描述中所提到的,步行位址測試(測試 0)和區塊移動測試(測試 7)不會影響 BadRAM 模式,因為這些測試不允許確定故障的確切位址。
Linux memmap 模式會累積並顯示錯誤記憶體區域,以便與 [Linux memmap 引導命令列選項] (https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt) 一起使用。行以memmap= S
$A1 S,A
memmap=S1$A1,S2,A2...
A
列印。最多可記錄 20 個故障記憶體區域。一旦發現超過20個連續故障位置的區域,區域將被合併,這意味著一些區域包括非故障位置。程式將嘗試最小化所包含的無故障位置的數量。
注意:如同各個測試描述中所提到的,步行位址測試(測試 0)和區塊移動測試(測試 7)不會導致故障記憶體區域,因為這些測試不允許故障的準確位址被確定。
壞頁模式會累積並顯示錯誤的記憶體頁號。這些可以與 Windows bcdedit 命令一起使用,將這些頁面新增到 Windows PFA 記憶體清單中。頁碼要麼顯示為單一十六進位數字(例如0x20
),要麼顯示為一系列十六進位頁碼(例如0x20..0x2a
)。最多可記錄 20 個範圍的錯誤頁面。一旦發現超過 20 個連續故障頁面範圍,範圍將合併,這表示某些範圍包含非故障頁面。程式將嘗試最小化所包含的無故障頁面的數量。
注意:正如各個測試描述中所提到的,步行地址測試(測試 0)和區塊移動測試(測試 7)不會對錯誤頁碼產生影響,因為這些測試不允許確定錯誤的確切地址。
請注意,並非 Memtest86+ 報告的所有錯誤都是由於記憶體不良造成的。此測試隱式測試 CPU、快取和主機板。測試不可能確定導致故障發生的原因。大多數失敗都是由於記憶體問題造成的。如果不是這樣,唯一的選擇就是更換零件,直到故障得到糾正。
一旦偵測到記憶體錯誤,確定故障模組就不是一個明確的過程。由於主機板供應商數量眾多,內存插槽的組合也可能很多,因此要收集有關特定錯誤如何映射到故障內存模組的完整信息,即使不是不可能,也是很困難的。然而,可以採取一些步驟來確定故障模組。以下是您可能想要使用的一些技術:
移除模組
旋轉模組
更換模組
有時,由於組件不相容,會出現記憶體錯誤。記憶體模組可能在一個系統中運作正常,但在另一個系統中則不然。這並不罕見,也是造成混亂的根源。這些組件不一定是壞的,但可能需要避免某些組合。
在絕大多數情況下,Memtest86+ 報告的錯誤都是有效的。有些系統會導致 Memtest86+ 對記憶體大小感到困惑,並且會嘗試測試不存在的記憶體。這將導致大量連續位址被報告為錯誤,並且通常會有許多位元出錯。如果故障地址的數量相對較少,並且只有一兩個錯誤,則可以確定這些錯誤是有效的。此外,間歇性錯誤始終有效。
所有有效的記憶體錯誤都應該被修正。正常操作中可能永遠不會出現特定錯誤。然而,使用邊際記憶體進行操作是有風險的,可能會導致資料遺失甚至磁碟損壞。
Memtest86+無法診斷多種類型的PC故障。例如,導致作業系統崩潰的 CPU 故障很可能會導致 Memtest86+ 以相同的方式崩潰。
完全通過 Memtest86+ 所需的時間會根據 CPU 速度、記憶體速度和記憶體大小的不同而有很大差異。 Memtest86+ 無限期執行。每次執行所有選定的測試時,通過計數器都會增加。一般來說,一次通過就足以捕捉除最隱藏的錯誤之外的所有錯誤。然而,當懷疑出現間歇性錯誤時,為了獲得完全的信心,建議進行較長時間的測試。
有很多測試記憶力的好方法。然而,許多測試只是簡單地向記憶體拋出一些模式,而沒有過多考慮或了解記憶體架構或如何最好地檢測錯誤。這對於硬內存故障來說效果很好,但對於發現間歇性錯誤幾乎沒有作用。基於 BIOS 的記憶體測試對於發現間歇性記憶體錯誤毫無用處。
記憶體晶片由大量緊密密封的儲存單元組成,每個儲存單元對應一位資料。絕大多數間歇性故障是這些儲存單元之間相互作用的結果。通常,寫入儲存單元可能會導致相鄰單元之一被寫入相同的資料。有效的記憶測試試圖測試這種情況。因此,測試記憶體的理想策略如下:
顯然,該策略需要準確了解儲存單元在晶片上的佈局方式。此外,針對不同晶片類型和製造商,可能的晶片佈局數量無窮無盡,使得這種策略不切實際。然而,有一些測試演算法可以近似這種理想策略。
Memtest86+ 使用兩種演算法提供上述理想測試策略的合理近似。第一個策略稱為移動反轉。移動反轉測試的工作原理如下:
該演算法非常接近理想的記憶體測試,但存在一些限制。如今大多數高密度晶片都儲存 4 至 16 位元寬的資料。對於超過一位寬的晶片,不可能選擇性地只讀取或寫入一位。這意味著我們不能保證所有相鄰細胞都經過了相互作用測試。在這種情況下,我們能做的最好的事情就是使用一些模式來確保所有相鄰單元至少都已寫入所有可能的一和零組合。
還可以看出,快取、緩衝和亂序執行都會幹擾移動反轉演算法並使其效率降低。可以關閉緩存,但新高效能晶片中的記憶體緩衝無法停用。為了解決這個限制,創建了一個名為 Modulo-20 的新演算法。該演算法不受快取或緩衝的影響。該演算法的工作原理如下:
該演算法幾乎可以完成與移動反轉相同程度的鄰接測試,但不受快取或緩衝的影響。由於對所有記憶體進行了單獨的寫入傳遞(1.1、1.2)和讀取傳遞(1.4),因此我們可以確保所有緩衝區和高速緩存都已在傳遞之間刷新。選擇 20 作為步幅有點隨意。更大的步伐可能更有效,但執行起來會花費更長的時間。選擇 20 似乎是速度和徹底之間的合理折衷。
Memtest86+ 執行一系列編號測試來檢查錯誤。這些測試由測試演算法、資料模式和快取的組合組成。這些測試的執行順序經過精心安排,以便盡快偵測到錯誤。每個測試的描述如下。
為了允許在 32 位元 CPU 上測試超過 4GB 的內存,物理位址範圍被分為 1GB 窗口,每次將一個窗口映射到虛擬內存窗口。每個 1GB 視窗可能包含一個或多個連續的記憶體區域。對於大多數測試,測試是依次在每個記憶體區域上執行的。除第一個測試外,所有測試均啟用快取。
在每個記憶體區域中,使用步行位址模式依序測試所有位址位。此測試中的錯誤不會導致 BadRAM 模式、memmap 區域或壞頁區域。
在每個記憶體區域中,每個位址依序寫入自己的位址,然後檢查每個位址的一致性。無論使用者選擇哪種 CPU 排序模式,都會對每個可用的 CPU 依序執行此測試。
在所有記憶體區域中,每個位址都寫入自己的虛擬位址加上視窗號(對於 32 位元影像)或自己的實體位址(對於 64 位元影像),然後檢查每個位址的一致性。這可以捕獲高階位址位元中的任何錯誤,這些錯誤在依次測試每個視窗時可能會被遺漏。無論使用者選擇哪種 CPU 排序模式,都會對每個可用的 CPU 依序執行此測試。
在每個記憶體區域中,依序針對每個模式,使用具有全 1 和全 0 模式的移動反轉演算法。
在每個儲存區域中,依序針對每個模式,使用具有 8 位元寬步行 1 和步行 0 模式的移動反轉演算法。
在每個儲存區域中,依序針對每個模式,使用具有隨機數及其補碼模式的移動反轉演算法。每次測試通過的隨機數都不同,因此多次通過可以提高有效性。
在每個記憶體區域中,依序對每個模式使用行動反轉演算法,其中模式為 32 位元寬(在 32 位元建置上)或 64 位元寬(在 64 位元建置上)移動 1 和移動 0 。與先前的測試不同,該模式在每個連續位址上循環 1 位元。
該測試透過使用區塊移動 (movs) 指令來強調內存,並且基於 Robert Redelmeier 的 burnBX 測試。
在每個記憶體區域中,記憶體依序使用每 8 個位元組反轉一次的移位模式進行初始化。然後使用 movs 指令移動記憶體塊。移動完成後,檢查資料模式。由於僅在記憶體移動完成後才檢查數據,因此無法知道錯誤發生在哪裡。報告的地址僅適用於發現不良模式的位置。因此,此測試中的錯誤不會導致 BadRAM 模式、memmap 區域或壞頁區域。
在每個記憶體區域中,依序寫入每個位址隨機數,然後檢查每個位址的一致性,並寫入原始資料的補碼,然後再次檢查每個位址的一致性。
在每個記憶體區域中,依序針對每個模式,使用具有隨機數及其補碼模式的 Modulo-20 演算法。每次測試通過的隨機數都不同,因此多次通過可以提高有效性。
跨所有記憶體區域,依序針對每個模式,用模式初始化每個記憶體位置,休眠一段時間,然後檢查每個記憶體位置的一致性。使用全零和全一的模式執行測試。
請參閱 GitHub 上的未決問題和增強請求清單。
請隨時提交錯誤報告!
歡迎貢獻程式碼,無論是修復錯誤還是進行增強。請參閱 doc 目錄中的 README_DEVEL.md 以了解一些基本指南。
Memtest86+ v6.0 是基於 Martin Whitaker 開發的 PCMemTest,後者基於 Samuel Demeulemeester 開發的 Memtest86+ v5.01,而後者又基於 Chris Brady 開發的 Memtest86,並獲得了下列資源和幫助:
原始檔 bootsect.S、setup.S、head.S 和 build.c 的初始版本來自 Linux 1.2.1 內核,並已進行了大量修改。
Doug Sisk 提供了支援透過序列埠連接的控制台的程式碼。 (目前未使用)
建立 BadRAM 模式的程式碼由 Rick van Rein 提供。
區塊移動測試基於 Robert Redelmeier 的 burnBX 測試。
螢幕緩衝區代碼由 Jani Averbach 提供。 (Memtest86+ v6.0 未使用)
Eric Biederman 提供了 3.0 版的所有功能內容以及許多錯誤修復和重要的程式碼清理。
Samuel Demeulemeester(來自 Memtest86+ v1.11、v1.60 和 v1.70)在 3.2、3.3 和 3.4 版中對硬體檢測和報告進行了重大增強。
此外,也從 anphsw/memtest86 匯入了 Memtest86+ 的多個錯誤修復。