memtest86plus/memtest86plus
GitHub: memtest86plus/memtest86plus
Memtest86+ 是一款开源独立的内存硬件诊断工具,通过多种测试算法彻底检测 x86 和 LoongArch64 平台上的内存错误和间歇性故障。
Stars: 1656 | Forks: 127
# Memtest86+
Memtest86+ 是一款免费的、开源的独立内存测试工具,适用于 x86、x86-64 和 LoongArch64 架构的计算机。它提供的内存检查比 BIOS 内存测试更加彻底。
它还能够访问计算机几乎所有的内存,不受操作系统所用内存的限制,也不依赖于任何底层软件(如 UEFI 库)。
Memtest86+ 可以直接由 PC BIOS(传统 BIOS 或 UEFI)加载和运行,也可以通过支持 Linux 16 位、32 位、64 位或 EFI 交接启动协议的中间引导加载程序来运行。它应该能在大多数 x86、x86-64 CPU(奔腾级别或更新的 32 位或 64 位)以及大多数 LoongArch64 CPU(龙芯 3 和龙芯 2 系列)上运行。
二进制发行版(包括稳定版和夜间开发版)可在 [memtest.org](https://memtest.org) 获取。
## 目录
* [起源](#origins)
* [许可协议](#licensing)
* [构建与安装](#build-and-installation)
* [启动选项](#boot-options)
* [键盘选择](#keyboard-selection)
* [操作说明](#operation)
* [错误显示](#error-reporting)
* [内存错误故障排除](#trouble-shooting-memory-errors)
* [执行时间](#execution-time)
* [Memtest86+ 测试算法](#memory-testing-philosophy)
* [各测试详细说明](#individual-test-descriptions)
* [已知限制与缺陷](#known-limitations-and-bugs)
* [代码贡献](#code-contributions)
* [致谢](#acknowledgments)
## 起源
Memtest86+ v6.00 基于 PCMemTest,而 PCMemTest 是早期 Memtest86+ v5 的一个分支和重写版本,Memtest86+ v5 本身又是 MemTest-86 的一个分支。PCMemTest 重写的目的是:
* 使代码更易读、更易维护
* 使代码兼容 64 位并支持 UEFI 启动
* 修复使用较新版本 GCC 构建时出现的故障
在创建 PCMemTest 的过程中,Memtest86+ v5 中一些并非严格用于系统内存测试的功能被舍弃了。特别是,没有尝试测量缓存和主内存速度,也没有尝试识别和报告 DRAM 类型。这些功能在 Memtest86+ v6.0 中被重新添加并扩展,以创建一个统一的、功能齐全的版本。
## 许可协议
Memtest86+ 根据 GNU 通用公共许可证第 2 版(GPLv2)的条款发布。除 GPL 条款外,对使用(无论是私人还是商业用途)没有任何限制。详情请参阅 LICENSE 文件。
## 构建与安装
构建仅在 Linux 系统上经过测试,但应可在任何使用 GNU 工具链和 ELF 文件格式的系统上完成。所需工具包括:
* GCC 或交叉编译 GCC
* binutils
* make
* dosfstools 和 mtools(可选)
* xorrisofs(可选)
### 构建 x86 32 位镜像
切换到 `build/i586` 目录并输入 `make`。结果是一个 `mt86plus` 二进制镜像文件,可以由 32 位 UEFI BIOS(如果命名为 mt86plus.efi)、传统 BIOS(软盘模式)直接启动,也可以使用 Linux 16 位启动协议由中间引导加载程序启动。该镜像也可以由中间引导加载程序使用 Linux 32 位或 32 位 EFI 交接启动协议启动。
### 构建 x86-64 64 位镜像
切换到 `build/x86_64` 目录并输入 `make`。结果是一个 `mt86plus` 二进制镜像文件,可以由 64 位 UEFI BIOS(如果命名为 mt86plus.efi)、传统 BIOS(软盘模式)直接启动,也可以使用 Linux 16 位启动协议由中间引导加载程序启动。该镜像也可以由中间引导加载程序使用 Linux 32 位、64 位或 64 位 EFI 交接启动协议启动。
### 构建 LoongArch64 64 位镜像
#### x86-64 Linux 环境
* 下载[交叉编译器](https://github.com/loongson/build-tools/releases)。
sudo mkdir /opt/LoongArch_Toolchains -p; cd /opt/LoongArch_Toolchains
使用 `wget` 下载最新版本或其他版本的交叉编译器。
* 配置交叉编译 GCC。
sudo tar -xvf x86_64-cross-tools-xxxxxx.tar.gz
export PATH=/opt/LoongArch_Toolchains/cross-tools/bin/:$PATH
* 返回 `memtest86plus` 目录
* 切换到 `build/loongarch64` 目录并执行 make。
cd build/loongarch64
make CC=loongarch64-unknown-linux-gnu-gcc LD=loongarch64-unknown-linux-gnu-ld OBJCOPY=loongarch64-unknown-linux-gnu-objcopy
#### LoongArch64 Linux 环境
切换到 `build/loongarch64` 目录并输入 `make`。
结果是一个 `mt86plus` 二进制镜像文件,可以由 64 位 UEFI BIOS(如果命名为 mt86plus.efi)直接启动,该镜像也可以由中间引导加载程序使用 64 位 EFI 交接启动协议启动。
在任一情况下,要构建可用于创建可启动 CD、DVD 或 USB 闪存驱动器的 ISO 镜像,输入 `make iso`。结果是一个 `memtest.iso` ISO 镜像文件。然后可以直接将其写入空白 CD 或 DVD,或写入 USB 闪存驱动器,随后可由传统或 UEFI PC BIOS 直接启动。
请注意,写入 USB 闪存驱动器时,ISO 镜像必须直接("转储")写入原始设备,可以使用 `dd` 命令或提供相同功能的工具。
使用中间引导加载程序时,`mt86plus` 文件应存储在引导加载程序可以访问的磁盘分区中,并应更新引导加载程序配置以从该文件启动,就像它是一个没有初始 RAM 磁盘的 Linux 内核一样。Memtest86+ 支持多个引导命令行选项,如下所述。如果使用 16 位启动协议,Memtest86+ 将使用文本模式(640x400)显示。如果使用 32 位或 64 位启动协议,Memtest86+ 将使用文本模式或图形模式显示,具体取决于引导加载程序传递给它的 `boot_params` 结构中指定的模式。如果处于图形模式,提供的帧缓冲区必须至少为 640x400 像素;如果更大,显示将居中。如果系统以 UEFI 模式启动,则必须使用图形模式。
出于测试目的,还有一个选项可以构建使用 GRUB 作为中间引导加载程序的 ISO 镜像。详情请参阅 `build` 目录下的各个 `Makefile`。该 ISO 镜像同时支持传统和 UEFI 启动,因此你的构建系统上需要安装传统和 EFI 启动所需的 GRUB 模块(例如,在 Debian 上,所需的 GRUB 模块位于 `grub-pc-bin`、`grub-efi-ia32-bin`、`grub-efi-amd64-bin` 和 `grub-efi-loong64-bin` 包中)。你可能需要调整 Makefile 中的一些路径和文件名以匹配你系统上的命名。
**附注。** LoongArch64 GRUB ISO 只能在 LoongArch64 Linux 环境中创建。 `grub` 目录中包含的 GRUB 配置文件用于测试 ISO,也可作为如何从 GRUB 启动 Memtest86+ 的示例。 ## 启动选项 中间引导加载程序可以向 Memtest86+ 传递引导命令行。命令行可以包含一个或多个选项,以空格分隔。每个选项由一个选项名称组成,可选地后跟一个 `=` 号和一个或多个参数,以逗号分隔。支持以下选项: * nosmp * 禁用 ACPI 表解析和多核 CPU 的使用 * nobench * 禁用集成的内存基准测试 * nobigstatus * 禁用大型 PASS/FAIL 弹出状态显示 * nosm * 禁用 SMBUS/SPD 解析、DMI 解码和内存基准测试 * nomch * 禁用内存控制器配置轮询 * nopause * 跳过启动时的配置暂停 * keyboard=*type* * 其中 *type* 为以下之一 * legacy * usb * both * dark * 将默认背景颜色从蓝色改为黑色 * screen.mode=*w*x*h*(仅限 EFI 帧缓冲区) * 其中 *w*x*h* 是首选屏幕分辨率(例如 1024x768) * screen.mode=bios(仅限 EFI 帧缓冲区) * 使用 UEFI BIOS 设置的默认屏幕分辨率 * screen.rhs-up(仅限图形模式) * 将显示顺时针旋转 90 度 * screen.lhs-up(仅限图形模式) * 将显示逆时针旋转 90 度 * efidebug * 显示有关 EFI 帧缓冲区的信息 * usbdebug * 在探测 USB 键盘后暂停 * usbinit=*mode* * 其中 *mode* 为以下之一 * 1 = 对高速设备使用两步初始化序列 * 2 = 在初始化序列中添加第二次 USB 复位 * 3 = 模式 1 和 2 的组合 * console=ttyS*x*,*y* * 激活串行/tty 控制台输出,其中 *x* 为以下 IO 端口之一 * 0 = 0x3F8 * 1 = 0x2F8 * 2 = 0x3E8 * 3 = 0x2E8 * *y* 是可选的波特率,从以下列表中选择 * 9600 * 19200 * 38400 * 57600 * 115200(未指定或无效时的默认值) * 230400 * console=*x*,*y* * 激活 MMIO UART 控制台,其中 *x* 是 MMIO 步幅(寄存器宽度) * mmio = 8 位 MMIO * mmio16 = 16 位 MMIO * mmio32 = 32 位 MMIO * *y* 是十六进制格式的 MMIO 地址,带有 `0x` 前缀(例如:0xFEDC9000) * newline * 修改控制台,使其在每次帧缓冲区变化后打印换行符 * 在通过串行记录时很有用,需要换行符或转行符 * 仅在使用控制台/串行输出时使用 * testlist=*x,y,z* * 其中 *x,y,z* 是要运行的测试的数值列表。 * 如果指定,初始测试配置将被修改,使列表中只有指定的测试处于活动状态。列表应以逗号分隔 例如:`testlist=0,1` 将只运行测试 0 和 1。 * ecc * 启用 ECC 轮询 ## 键盘选择 Memtest86+ 同时支持传统键盘接口(使用 I/O 或 MMIO 端口 0x60 和 0x64)和 USB 键盘(使用其自身的 USB 设备驱动程序)。可以通过引导命令行选择其中一个或两者。如果未在命令行中指定,默认值为:如果系统以 UEFI 模式启动则同时使用两者,否则仅使用传统接口。 较旧的 x86 或 x86-64 BIOS 通常支持 USB 传统键盘仿真,使 USB 键盘表现得像连接到端口 0x60 和 0x64 的传统键盘一样。这通常可以在 BIOS 设置菜单中启用或禁用。如果启用了 Memtest86+ 的 USB 设备驱动程序,它们将覆盖此设置并直接访问任何 USB 键盘。缺点是 USB 控制器和设备驱动程序需要预留一些内存供其私有使用,这意味着该内存随后无法被内存测试覆盖。因此,为了最大化测试覆盖率,如果支持的话,请启用 USB 传统键盘仿真,如果以 UEFI 模式启动,请在引导命令行中添加 `keyboard=legacy`。 **注意**:某些 UEFI BIOS 仅在你在 BIOS 设置中启用兼容性系统模块(CSM)时才支持 USB 传统键盘仿真。其他 BIOS 则仅在以传统模式实际启动时才支持它。 许多 USB 设备并不完全符合 USB 规范。如果 USB 键盘探测挂起或无法检测到你的键盘,请尝试 "usbinit" 启动选项提供的各种解决方法。 **注意**:Memtest86+ 的 USB 驱动程序目前不支持热插拔。使用这些驱动程序时,应在运行 Memtest86+ 之前插入 USB 键盘,并在整个测试过程中保持插入状态。 ## 显示旋转 某些二合一机器使用的 LCD 面板原生为竖屏模式显示,但在连接到键盘时侧向安装。在图形模式下使用显示时,Memtest86+ 可以旋转其显示以匹配。根据 LCD 面板的方向,在引导命令行中添加 "screen.rhs-up" 或 "screen.lhs-up" 选项。 在文本模式下使用显示时,预计 BIOS 会自动处理此问题。 ## 屏幕分辨率 以传统模式启动时,Memtest86+ 将使用 BIOS 或中间引导加载程序设置的屏幕分辨率。以 UEFI 模式启动时,Memtest86+ 通常会选择包含其 640x400 像素显示的最小可用屏幕分辨率。某些 BIOS 返回的可用显示模式信息不正确,因此你可以通过在引导命令行中添加 "screen.mode=" 选项来覆盖此设置。 请注意,使用显示旋转时,指定的屏幕分辨率是针对未旋转的显示。 ## 操作说明 启动后,Memtest86+ 将初始化其显示,然后暂停几秒钟以允许用户配置其操作。如果没有按键,它将自动开始使用单个 CPU 核心运行所有测试,持续运行直到用户重启或停止机器。 在启动时和运行测试时,Memtest86+ 响应以下按键: * F1 * 进入配置菜单 * F2 * 切换多核 CPU(SMP)的使用 * 空格 * 切换滚动锁定(停止/开始错误消息滚动) * 回车 * 单条消息滚动(仅在启用滚动锁定时) * Esc * 退出测试并重启机器 请注意,当启用滚动锁定且滚动区域已满时,测试将暂停。 配置菜单允许用户: * 选择要运行的测试(默认:所有测试) * 限制执行测试的地址范围(默认:所有内存) * 选择 CPU 排序模式(默认:并行) * 并行 * 每个 CPU 核心并行处理被测试内存区域的子集 * 顺序 * 每个 CPU 核心依次处理整个被测试内存区域 * 轮询 * 单个 CPU 核心处理整个被测试内存区域,每次测试选择一个新的 CPU 核心(以轮询方式) * 选择错误报告模式(默认:单个错误) * 仅错误计数 * 错误摘要 * 单个错误 * BadRAM 模式 * Linux memmap * 坏页 * 选择使用哪些可用的 CPU 核心(仅在启动时) * 由于内存和显示限制,最多可选择 256 个 CPU 核心 * 引导处理器(BSP)无法被取消选择 * 启用或禁用温度显示(仅在启动时) * 启用或禁用调试的引导跟踪(仅在启动时) * 跳到下一个测试(运行测试时) 在所有情况下,数字键可用作功能键的替代(1 = F1,2 = F2,... 0 = F10)。 ## 错误报告 可以随时更改错误报告模式,而不会中断当前测试序列。无论当前错误报告模式如何,都会收集错误统计信息(因此切换到错误摘要模式将显示自当前测试序列开始以来的累积统计信息)。BadRAM 模式仅在 BadRAM 模式下累积。Linux memmap 区域仅在 memmap 模式下累积。坏页编号仅在坏页模式下累积。 对所选测试、地址范围或 CPU 排序模式的任何更改都将开始新的测试序列并重置错误统计信息。 ### 仅错误计数 仅错误计数模式显示自当前测试序列开始以来发现的错误总数。 ### 错误摘要 错误摘要模式显示以下信息: * 最低错误地址 * 报告错误的最低地址 * 最高错误地址 * 报告错误的最高地址 * 错误位掩码 * 所有出错位的十六进制掩码 * 错误位数 * 所有错误实例的总出错位数,以及每个错误实例中出错位数的最小值、最大值和平均值 * 最大连续错误 * 有错误的连续地址的最大数量 * 测试错误 * 每个单独测试的错误总数 ### 单个错误 单个错误模式显示每个错误实例的以下信息: * pCPU * 检测到错误的物理 CPU 核心编号 * 通过 * 发生错误的测试通过编号(测试通过是对所有当前所选测试的一次完整运行) * 测试 * 发生错误的单独测试编号 * 故障地址 * 发生错误的内存地址 * 预期值 * 预期找到的十六进制数据模式 * 实际值 * 从故障地址读取的十六进制数据模式 * 错误位(仅在 32 位构建中) * 显示出错位的十六进制掩码 ### BadRAM 模式 BadRAM 模式累积并显示错误模式,供 [Linux BadRAM 功能](http://rick.vanrein.org/linux/badram/)或 [GRUB badram 命令](https://www.gnu.org/software/grub/manual/grub/grub.html#badram)使用。 行以 `badram=F1,M1,F2,M2...` 的形式打印。在每对 `F,M` 中,`F` 表示故障地址,`M` 是该地址的位掩码。这些模式表明在地址等于 M 中所有 `1` 位的 F 处发生了故障。这样的模式可能捕获比实际存在的更多的错误,但至少所有错误都被捕获。这些模式旨在以简洁的语法捕获由硬件结构引起的规则错误模式。 BadRAM 模式是递增增长的,而不是从所有错误的总览中计算出来的。由于实际原因,对数限制为 20。因此,在特殊情况下,从地址打印模式的输出中手工制作模式可能会产生更好的结果。 **注意** 如各测试详细说明中所述,行走 1 地址测试(测试 0)和块移动测试(测试 7)不会对 BadRAM 模式做出贡献,因为这些测试不允许确定故障的确切地址。 ### Linux memmap Linux memmap 模式累积并显示故障内存区域,供 [Linux memmap 引导命令行选项](https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt)使用。 行以 `memmap=S1$A1,S2,A2...` 的形式打印。在每对 `S,A` 中,`A` 表示区域中的第一个地址,`S` 是区域的大小(以字节为单位)。最多记录 20 个故障内存区域。一旦发现超过 20 个连续的故障位置区域,区域将被合并,这意味着某些区域包含非故障位置。程序将尽量减少包含的非故障位置数量。 **注意** 如各测试详细说明中所述,行走 1 地址测试(测试 0)和块移动测试(测试 7)不会对故障内存区域做出贡献,因为这些测试不允许确定故障的确切地址。 ### 坏页 坏页模式累积并显示故障内存页编号。这些可以与 Windows bcdedit 命令一起使用,将这些页面添加到 Windows PFA 内存列表中。页编号显示为单个十六进制数字(例如 `0x20`)或十六进制页编号范围(例如 `0x20..0x2a`)。最多记录 20 个故障页范围。一旦发现超过 20 个连续的故障页范围,范围将被合并,这意味着某些范围包含非故障页。程序将尽量减少包含的非故障页数量。 **注意** 如各测试详细说明中所述,行走 1 地址测试(测试 0)和块移动测试(测试 7)不会对故障页编号做出贡献,因为这些测试不允许确定故障的确切地址。 ## 内存错误故障排除 请注意,Memtest86+ 报告的所有错误并非都是由内存不良引起的。测试隐式测试了 CPU、缓存和主板。测试不可能确定故障发生的原因。大多数故障是由内存问题引起的。如果不是,唯一的选择是更换部件直到故障得到纠正。 一旦检测到内存内存错误,确定故障模块并不是一个明确的过程。由于主板供应商众多,内存插槽的可能组合也很多,要收集关于特定错误如何映射到故障内存模块的完整信息即使不是不可能,也是困难的。但是,可以采取一些步骤来确定故障模块。以下是一些你可能希望使用的技术: * 移除模块 * 这是隔离故障模块的最简单方法,但只有在可以从系统中移除一个或多个模块时才能使用。通过选择性地从系统中移除模块然后运行测试,你将能够找到故障模块。请务必准确记录测试通过和测试失败时系统中有哪些模块。 * 轮换模块 * 当无法移除任何模块时,你可以轮换模块以找到故障模块。此技术仅在系统中有三个或更多模块时才能使用。一次更换两个模块的位置。例如,将插槽 1 中的模块放入插槽 2,将插槽 2 中的模块放入插槽 1。运行测试,如果故障位或地址发生变化,你就知道故障模块是刚移动的那个。通过使用多种模块移动组合,你应该能够确定哪个模块出现故障。 * 更换模块 * 如果你无法使用上述任何技术,你只能选择性地更换模块来找到故障。 有时内存错误是由于组件不兼容引起的。一个内存模块在一个系统中可能正常工作,但在另一个系统中不行。这并不罕见,也是困惑的来源。组件不一定有问题,但某些组合可能需要避免。 在绝大多数情况下,Memtest86+ 报告的错误是有效的。有些系统会导致 Memtest86+ 对内存大小产生混淆,它会尝试测试不存在的内存。这将导致大量连续地址被报告为错误,通常会有许多位出错。如果你有相对较少的故障地址且只有一两个位出错,你可以确定这些错误是有效的。此外,间歇性错误总是有效的。 所有有效的内存错误都应该纠正。某个特定错误可能在正常操作中永远不会出现。但是,在临界状态下运行内存是有风险的,可能导致数据丢失甚至磁盘损坏。 Memtest86+ 无法诊断许多类型的 PC 故障。例如,导致操作系统崩溃的故障 CPU 很可能只会以同样的方式导致 Memtest86+ 崩溃。 ## 执行时间 Memtest86+ 完成一次完整通过所需的时间因 CPU 速度、内存速度和内存大小的不同而有很大差异。Memtest86+ 无限期执行。每次运行完所有所选测试后,通过计数器就会递增。通常一次通过足以捕获除最隐蔽的错误之外的所有错误。但是,当怀疑有间歇性错误时,建议进行更长时间的测试。 ## 内存测试理念 有许多测试内存的好方法。然而,许多测试只是简单地向内存抛出一些模式,而没有太多考虑或对内存架构或如何最好地检测错误的了解。这对于硬性内存故障很有效,但对发现间歇性错误几乎没有帮助。基于 BIOS 的内存测试对于发现间歇性内存错误毫无用处。 内存芯片由紧密排列的大量内存单元阵列组成,每个数据位对应一个内存单元。绝大多数间歇性故障是这些内存单元之间相互作用的结果。通常,写入一个内存单元会导致相邻单元之一被写入相同的数据。有效的内存测试试图测试这种情况。因此,测试内存的理想策略如下: 1. 用零写入一个单元 2. 用一写入所有相邻单元,一次或多次 3. 检查第一个单元是否仍为零 很明显,此策略需要确切了解内存芯片上内存单元的布局。此外,不同的芯片类型和制造商有无穷无尽的可能芯片布局,使此策略不切实际。但是,有一些测试算法可以近似这种理想策略。 ## Memtest86+ 测试算法 Memtest86+ 使用两种算法,它们提供了上述理想测试策略的合理近似。第一种策略称为移动反转。移动反转测试的工作原理如下: 1. 用模式填充内存 2. 从最低地址开始 1. 检查模式是否未改变 2. 写入模式的反码 3. 递增地址 4. 重复 2.1 到 2.3 3. 从最高地址开始 1. 检查模式是否未改变 2. 写入模式的反码 3. 递减地址 4. 重复 3.1 到 3.3 此算法是理想内存测试的良好近似,但存在一些限制。今天的大多数高密度芯片以 4 到 16 位宽存储数据。对于宽度超过一位的芯片,无法选择性地只读取或写入一位。这意味着我们无法保证所有相邻单元都经过了交互测试。在这种情况下,我们所能做的就是使用一些模式来确保所有相邻单元至少已经写入了所有可能的一和零组合。 还可以看出,缓存、缓冲和乱序执行会干扰移动反转算法并降低其效果。可以关闭缓存,但新的高性能芯片中的内存缓冲无法禁用。为了解决这一限制,创建了一种称为 Modulo-20 的新算法。此算法不受缓存或缓冲的影响。算法的工作原理如下: 1. 对于 0 - 19 的起始偏移量 1. 每隔 20 个位置写入一个模式 2. 用模式的反码写入所有其他位置 3. 重复 1.2 一次或多次 4. 每隔 20 个位置检查模式 此算法实现了与移动反转几乎相同的邻接测试水平,但不受缓存或缓冲的影响。由于单独的写入遍(1.1、1.2)和读取遍(1.4)是针对所有内存完成的,我们可以确保各遍之间的所有缓冲区和缓存都已刷新。选择 20 作为步长是有些任意的。更大的步长可能更有效,但执行时间会更长。选择 20 似乎是速度和彻底性之间的合理折衷。 ## 各测试详细说明 Memtest86+ 执行一系列编号的测试来检查错误。这些测试由测试算法、数据和缓存的组合组成。这些测试的执行顺序安排为使错误能够尽快检测出来。以下是每个测试的说明。 为了允许在 32 位 CPU 上测试超过 4GB 的内存,物理地址范围被分成 1GB 窗口,这些窗口一次一个地映射到虚拟内存窗口中。每个 1GB 窗口可能包含一个或多个连续的内存区域。对于大多数测试,测试依次在每个内存区域上执行。除第一个测试外,所有测试都启用了缓存。 ### 测试 0:地址测试,行走 1,无缓存 在每个内存区域中,使用行走 1 地址模式测试所有地址位。此测试的错误不会对 BadRAM 模式、memmap 区域或坏页区域做出贡献。 ### 测试 1:地址测试,窗口内的自身地址 在每个内存区域中,每个地址写入其自身的地址,然后检查每个地址的一致性。此测试与每个可用的 CPU 顺序执行,无论用户选择何种 CPU 排序模式。 ### 测试 2:地址测试,自身地址 + 窗口 在所有内存区域中,每个地址写入其自身的虚拟地址加上窗口编号(对于 32 位镜像)或自身物理地址(对于 64 位镜像),然后检查每个地址的一致性。这可以捕获在逐个窗口测试时会被遗漏的高阶地址位中的任何错误。此测试与每个可用的 CPU 顺序执行,无论用户选择何种 CPU 排序模式。 ### 测试 3:移动反转,全 1 和全 0 在每个内存区域中,依次对每个模式使用全 1 和全 0 模式的移动反转算法。 ### 测试 4:移动反转,8 位模式 在每个内存区域中,依次对每个模式使用 8 位宽行走 1 和行走 0 模式的移动反转算法。 ### 测试 5:移动反转,随机模式 在每个内存区域中,依次对每个模式使用随机数及其反码模式的移动反转算法。随机数在每次测试通过时都不同,因此多次通过会增加有效性。 ### 测试 6:移动反转,32/64 位模式 在每个内存区域中,依次对每个模式使用 32 位宽(在 32 位构建上)或 64 位宽(在 64 位构建上)行走 1 和行走 0 模式的移动反转算法。与之前的测试不同,模式在每个连续地址上旋转 1 位。 ### 测试 7:块移动,64 次移动 此测试通过使用块移动(movs)指令对内存施加压力,基于 Robert Redelmeier 的 burnBX 测试。 在每个内存区域中,内存用每 8 字节反转一次的移位模式初始化。然后使用 movs 指令移动内存块。移动完成后检查数据模式。因为只有在内存移动完成后才检查数据,所以不可能知道错误发生在哪里。报告的地址仅是针对发现错误模式的位置。因此,此测试的错误不会对 BadRAM 模式、memmap 区域或坏页区域做出贡献。 ### 测试 8:随机数序列 在每个内存区域中,每个地址写入一个随机数,然后检查每个地址的一致性并用原始数据的反码写入,然后再次检查每个地址的一致性。 ### 测试ulo 20,随机模式 在每个内存区域中,依次对每个模式使用随机数及其反码模式的 Modulo-20 算法。随机数在每次测试通过时都不同,因此多次通过会增加有效性。 ### 测试 10:位衰减测试,2 种模式 在所有内存区域中,依次对每个模式,用模式初始化每个内存位置,休眠一段时间,然后检查每个内存位置的一致性。测试使用全 0 和全 1 的模式执行。 ## 已知限制与缺陷 请参阅 GitHub 上的[开放问题](https://github.com/memtest86plus/memtest86plus/issues)和[增强请求](https://github.com/memtest86plus/memtest86plus/discussions)列表。 欢迎提交缺陷报告! ## 代码贡献 欢迎代码贡献,无论是修复缺陷还是进行增强。请参阅 doc 目录中的 README_DEVEL.md 了解一些基本指南。 ## 致谢 Memtest86+ v6.0 基于 Martin Whitaker 开发的 PCMemTest,PCMemTest 基于 Samuel Demeulemeester 开发的 Memtest86+ v5.01,而 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 版的所有功能内容以及大量缺陷修复和重要的代码清理。 * 3.2、3.3 和 3.4 版中硬件检测和报告的重大增强由 Samuel Demeulemeester 提供(来自 Memtest86+ v1.11、v1.60 和 v1.70)。 此外,Memtest86+ 的多项缺陷修复是从 [anphsw/memtest86](https://github.com/anphsw/memtest86) 导入的。
**附注。** LoongArch64 GRUB ISO 只能在 LoongArch64 Linux 环境中创建。 `grub` 目录中包含的 GRUB 配置文件用于测试 ISO,也可作为如何从 GRUB 启动 Memtest86+ 的示例。 ## 启动选项 中间引导加载程序可以向 Memtest86+ 传递引导命令行。命令行可以包含一个或多个选项,以空格分隔。每个选项由一个选项名称组成,可选地后跟一个 `=` 号和一个或多个参数,以逗号分隔。支持以下选项: * nosmp * 禁用 ACPI 表解析和多核 CPU 的使用 * nobench * 禁用集成的内存基准测试 * nobigstatus * 禁用大型 PASS/FAIL 弹出状态显示 * nosm * 禁用 SMBUS/SPD 解析、DMI 解码和内存基准测试 * nomch * 禁用内存控制器配置轮询 * nopause * 跳过启动时的配置暂停 * keyboard=*type* * 其中 *type* 为以下之一 * legacy * usb * both * dark * 将默认背景颜色从蓝色改为黑色 * screen.mode=*w*x*h*(仅限 EFI 帧缓冲区) * 其中 *w*x*h* 是首选屏幕分辨率(例如 1024x768) * screen.mode=bios(仅限 EFI 帧缓冲区) * 使用 UEFI BIOS 设置的默认屏幕分辨率 * screen.rhs-up(仅限图形模式) * 将显示顺时针旋转 90 度 * screen.lhs-up(仅限图形模式) * 将显示逆时针旋转 90 度 * efidebug * 显示有关 EFI 帧缓冲区的信息 * usbdebug * 在探测 USB 键盘后暂停 * usbinit=*mode* * 其中 *mode* 为以下之一 * 1 = 对高速设备使用两步初始化序列 * 2 = 在初始化序列中添加第二次 USB 复位 * 3 = 模式 1 和 2 的组合 * console=ttyS*x*,*y* * 激活串行/tty 控制台输出,其中 *x* 为以下 IO 端口之一 * 0 = 0x3F8 * 1 = 0x2F8 * 2 = 0x3E8 * 3 = 0x2E8 * *y* 是可选的波特率,从以下列表中选择 * 9600 * 19200 * 38400 * 57600 * 115200(未指定或无效时的默认值) * 230400 * console=*x*,*y* * 激活 MMIO UART 控制台,其中 *x* 是 MMIO 步幅(寄存器宽度) * mmio = 8 位 MMIO * mmio16 = 16 位 MMIO * mmio32 = 32 位 MMIO * *y* 是十六进制格式的 MMIO 地址,带有 `0x` 前缀(例如:0xFEDC9000) * newline * 修改控制台,使其在每次帧缓冲区变化后打印换行符 * 在通过串行记录时很有用,需要换行符或转行符 * 仅在使用控制台/串行输出时使用 * testlist=*x,y,z* * 其中 *x,y,z* 是要运行的测试的数值列表。 * 如果指定,初始测试配置将被修改,使列表中只有指定的测试处于活动状态。列表应以逗号分隔 例如:`testlist=0,1` 将只运行测试 0 和 1。 * ecc * 启用 ECC 轮询 ## 键盘选择 Memtest86+ 同时支持传统键盘接口(使用 I/O 或 MMIO 端口 0x60 和 0x64)和 USB 键盘(使用其自身的 USB 设备驱动程序)。可以通过引导命令行选择其中一个或两者。如果未在命令行中指定,默认值为:如果系统以 UEFI 模式启动则同时使用两者,否则仅使用传统接口。 较旧的 x86 或 x86-64 BIOS 通常支持 USB 传统键盘仿真,使 USB 键盘表现得像连接到端口 0x60 和 0x64 的传统键盘一样。这通常可以在 BIOS 设置菜单中启用或禁用。如果启用了 Memtest86+ 的 USB 设备驱动程序,它们将覆盖此设置并直接访问任何 USB 键盘。缺点是 USB 控制器和设备驱动程序需要预留一些内存供其私有使用,这意味着该内存随后无法被内存测试覆盖。因此,为了最大化测试覆盖率,如果支持的话,请启用 USB 传统键盘仿真,如果以 UEFI 模式启动,请在引导命令行中添加 `keyboard=legacy`。 **注意**:某些 UEFI BIOS 仅在你在 BIOS 设置中启用兼容性系统模块(CSM)时才支持 USB 传统键盘仿真。其他 BIOS 则仅在以传统模式实际启动时才支持它。 许多 USB 设备并不完全符合 USB 规范。如果 USB 键盘探测挂起或无法检测到你的键盘,请尝试 "usbinit" 启动选项提供的各种解决方法。 **注意**:Memtest86+ 的 USB 驱动程序目前不支持热插拔。使用这些驱动程序时,应在运行 Memtest86+ 之前插入 USB 键盘,并在整个测试过程中保持插入状态。 ## 显示旋转 某些二合一机器使用的 LCD 面板原生为竖屏模式显示,但在连接到键盘时侧向安装。在图形模式下使用显示时,Memtest86+ 可以旋转其显示以匹配。根据 LCD 面板的方向,在引导命令行中添加 "screen.rhs-up" 或 "screen.lhs-up" 选项。 在文本模式下使用显示时,预计 BIOS 会自动处理此问题。 ## 屏幕分辨率 以传统模式启动时,Memtest86+ 将使用 BIOS 或中间引导加载程序设置的屏幕分辨率。以 UEFI 模式启动时,Memtest86+ 通常会选择包含其 640x400 像素显示的最小可用屏幕分辨率。某些 BIOS 返回的可用显示模式信息不正确,因此你可以通过在引导命令行中添加 "screen.mode=" 选项来覆盖此设置。 请注意,使用显示旋转时,指定的屏幕分辨率是针对未旋转的显示。 ## 操作说明 启动后,Memtest86+ 将初始化其显示,然后暂停几秒钟以允许用户配置其操作。如果没有按键,它将自动开始使用单个 CPU 核心运行所有测试,持续运行直到用户重启或停止机器。 在启动时和运行测试时,Memtest86+ 响应以下按键: * F1 * 进入配置菜单 * F2 * 切换多核 CPU(SMP)的使用 * 空格 * 切换滚动锁定(停止/开始错误消息滚动) * 回车 * 单条消息滚动(仅在启用滚动锁定时) * Esc * 退出测试并重启机器 请注意,当启用滚动锁定且滚动区域已满时,测试将暂停。 配置菜单允许用户: * 选择要运行的测试(默认:所有测试) * 限制执行测试的地址范围(默认:所有内存) * 选择 CPU 排序模式(默认:并行) * 并行 * 每个 CPU 核心并行处理被测试内存区域的子集 * 顺序 * 每个 CPU 核心依次处理整个被测试内存区域 * 轮询 * 单个 CPU 核心处理整个被测试内存区域,每次测试选择一个新的 CPU 核心(以轮询方式) * 选择错误报告模式(默认:单个错误) * 仅错误计数 * 错误摘要 * 单个错误 * BadRAM 模式 * Linux memmap * 坏页 * 选择使用哪些可用的 CPU 核心(仅在启动时) * 由于内存和显示限制,最多可选择 256 个 CPU 核心 * 引导处理器(BSP)无法被取消选择 * 启用或禁用温度显示(仅在启动时) * 启用或禁用调试的引导跟踪(仅在启动时) * 跳到下一个测试(运行测试时) 在所有情况下,数字键可用作功能键的替代(1 = F1,2 = F2,... 0 = F10)。 ## 错误报告 可以随时更改错误报告模式,而不会中断当前测试序列。无论当前错误报告模式如何,都会收集错误统计信息(因此切换到错误摘要模式将显示自当前测试序列开始以来的累积统计信息)。BadRAM 模式仅在 BadRAM 模式下累积。Linux memmap 区域仅在 memmap 模式下累积。坏页编号仅在坏页模式下累积。 对所选测试、地址范围或 CPU 排序模式的任何更改都将开始新的测试序列并重置错误统计信息。 ### 仅错误计数 仅错误计数模式显示自当前测试序列开始以来发现的错误总数。 ### 错误摘要 错误摘要模式显示以下信息: * 最低错误地址 * 报告错误的最低地址 * 最高错误地址 * 报告错误的最高地址 * 错误位掩码 * 所有出错位的十六进制掩码 * 错误位数 * 所有错误实例的总出错位数,以及每个错误实例中出错位数的最小值、最大值和平均值 * 最大连续错误 * 有错误的连续地址的最大数量 * 测试错误 * 每个单独测试的错误总数 ### 单个错误 单个错误模式显示每个错误实例的以下信息: * pCPU * 检测到错误的物理 CPU 核心编号 * 通过 * 发生错误的测试通过编号(测试通过是对所有当前所选测试的一次完整运行) * 测试 * 发生错误的单独测试编号 * 故障地址 * 发生错误的内存地址 * 预期值 * 预期找到的十六进制数据模式 * 实际值 * 从故障地址读取的十六进制数据模式 * 错误位(仅在 32 位构建中) * 显示出错位的十六进制掩码 ### BadRAM 模式 BadRAM 模式累积并显示错误模式,供 [Linux BadRAM 功能](http://rick.vanrein.org/linux/badram/)或 [GRUB badram 命令](https://www.gnu.org/software/grub/manual/grub/grub.html#badram)使用。 行以 `badram=F1,M1,F2,M2...` 的形式打印。在每对 `F,M` 中,`F` 表示故障地址,`M` 是该地址的位掩码。这些模式表明在地址等于 M 中所有 `1` 位的 F 处发生了故障。这样的模式可能捕获比实际存在的更多的错误,但至少所有错误都被捕获。这些模式旨在以简洁的语法捕获由硬件结构引起的规则错误模式。 BadRAM 模式是递增增长的,而不是从所有错误的总览中计算出来的。由于实际原因,对数限制为 20。因此,在特殊情况下,从地址打印模式的输出中手工制作模式可能会产生更好的结果。 **注意** 如各测试详细说明中所述,行走 1 地址测试(测试 0)和块移动测试(测试 7)不会对 BadRAM 模式做出贡献,因为这些测试不允许确定故障的确切地址。 ### Linux memmap Linux memmap 模式累积并显示故障内存区域,供 [Linux memmap 引导命令行选项](https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt)使用。 行以 `memmap=S1$A1,S2,A2...` 的形式打印。在每对 `S,A` 中,`A` 表示区域中的第一个地址,`S` 是区域的大小(以字节为单位)。最多记录 20 个故障内存区域。一旦发现超过 20 个连续的故障位置区域,区域将被合并,这意味着某些区域包含非故障位置。程序将尽量减少包含的非故障位置数量。 **注意** 如各测试详细说明中所述,行走 1 地址测试(测试 0)和块移动测试(测试 7)不会对故障内存区域做出贡献,因为这些测试不允许确定故障的确切地址。 ### 坏页 坏页模式累积并显示故障内存页编号。这些可以与 Windows bcdedit 命令一起使用,将这些页面添加到 Windows PFA 内存列表中。页编号显示为单个十六进制数字(例如 `0x20`)或十六进制页编号范围(例如 `0x20..0x2a`)。最多记录 20 个故障页范围。一旦发现超过 20 个连续的故障页范围,范围将被合并,这意味着某些范围包含非故障页。程序将尽量减少包含的非故障页数量。 **注意** 如各测试详细说明中所述,行走 1 地址测试(测试 0)和块移动测试(测试 7)不会对故障页编号做出贡献,因为这些测试不允许确定故障的确切地址。 ## 内存错误故障排除 请注意,Memtest86+ 报告的所有错误并非都是由内存不良引起的。测试隐式测试了 CPU、缓存和主板。测试不可能确定故障发生的原因。大多数故障是由内存问题引起的。如果不是,唯一的选择是更换部件直到故障得到纠正。 一旦检测到内存内存错误,确定故障模块并不是一个明确的过程。由于主板供应商众多,内存插槽的可能组合也很多,要收集关于特定错误如何映射到故障内存模块的完整信息即使不是不可能,也是困难的。但是,可以采取一些步骤来确定故障模块。以下是一些你可能希望使用的技术: * 移除模块 * 这是隔离故障模块的最简单方法,但只有在可以从系统中移除一个或多个模块时才能使用。通过选择性地从系统中移除模块然后运行测试,你将能够找到故障模块。请务必准确记录测试通过和测试失败时系统中有哪些模块。 * 轮换模块 * 当无法移除任何模块时,你可以轮换模块以找到故障模块。此技术仅在系统中有三个或更多模块时才能使用。一次更换两个模块的位置。例如,将插槽 1 中的模块放入插槽 2,将插槽 2 中的模块放入插槽 1。运行测试,如果故障位或地址发生变化,你就知道故障模块是刚移动的那个。通过使用多种模块移动组合,你应该能够确定哪个模块出现故障。 * 更换模块 * 如果你无法使用上述任何技术,你只能选择性地更换模块来找到故障。 有时内存错误是由于组件不兼容引起的。一个内存模块在一个系统中可能正常工作,但在另一个系统中不行。这并不罕见,也是困惑的来源。组件不一定有问题,但某些组合可能需要避免。 在绝大多数情况下,Memtest86+ 报告的错误是有效的。有些系统会导致 Memtest86+ 对内存大小产生混淆,它会尝试测试不存在的内存。这将导致大量连续地址被报告为错误,通常会有许多位出错。如果你有相对较少的故障地址且只有一两个位出错,你可以确定这些错误是有效的。此外,间歇性错误总是有效的。 所有有效的内存错误都应该纠正。某个特定错误可能在正常操作中永远不会出现。但是,在临界状态下运行内存是有风险的,可能导致数据丢失甚至磁盘损坏。 Memtest86+ 无法诊断许多类型的 PC 故障。例如,导致操作系统崩溃的故障 CPU 很可能只会以同样的方式导致 Memtest86+ 崩溃。 ## 执行时间 Memtest86+ 完成一次完整通过所需的时间因 CPU 速度、内存速度和内存大小的不同而有很大差异。Memtest86+ 无限期执行。每次运行完所有所选测试后,通过计数器就会递增。通常一次通过足以捕获除最隐蔽的错误之外的所有错误。但是,当怀疑有间歇性错误时,建议进行更长时间的测试。 ## 内存测试理念 有许多测试内存的好方法。然而,许多测试只是简单地向内存抛出一些模式,而没有太多考虑或对内存架构或如何最好地检测错误的了解。这对于硬性内存故障很有效,但对发现间歇性错误几乎没有帮助。基于 BIOS 的内存测试对于发现间歇性内存错误毫无用处。 内存芯片由紧密排列的大量内存单元阵列组成,每个数据位对应一个内存单元。绝大多数间歇性故障是这些内存单元之间相互作用的结果。通常,写入一个内存单元会导致相邻单元之一被写入相同的数据。有效的内存测试试图测试这种情况。因此,测试内存的理想策略如下: 1. 用零写入一个单元 2. 用一写入所有相邻单元,一次或多次 3. 检查第一个单元是否仍为零 很明显,此策略需要确切了解内存芯片上内存单元的布局。此外,不同的芯片类型和制造商有无穷无尽的可能芯片布局,使此策略不切实际。但是,有一些测试算法可以近似这种理想策略。 ## Memtest86+ 测试算法 Memtest86+ 使用两种算法,它们提供了上述理想测试策略的合理近似。第一种策略称为移动反转。移动反转测试的工作原理如下: 1. 用模式填充内存 2. 从最低地址开始 1. 检查模式是否未改变 2. 写入模式的反码 3. 递增地址 4. 重复 2.1 到 2.3 3. 从最高地址开始 1. 检查模式是否未改变 2. 写入模式的反码 3. 递减地址 4. 重复 3.1 到 3.3 此算法是理想内存测试的良好近似,但存在一些限制。今天的大多数高密度芯片以 4 到 16 位宽存储数据。对于宽度超过一位的芯片,无法选择性地只读取或写入一位。这意味着我们无法保证所有相邻单元都经过了交互测试。在这种情况下,我们所能做的就是使用一些模式来确保所有相邻单元至少已经写入了所有可能的一和零组合。 还可以看出,缓存、缓冲和乱序执行会干扰移动反转算法并降低其效果。可以关闭缓存,但新的高性能芯片中的内存缓冲无法禁用。为了解决这一限制,创建了一种称为 Modulo-20 的新算法。此算法不受缓存或缓冲的影响。算法的工作原理如下: 1. 对于 0 - 19 的起始偏移量 1. 每隔 20 个位置写入一个模式 2. 用模式的反码写入所有其他位置 3. 重复 1.2 一次或多次 4. 每隔 20 个位置检查模式 此算法实现了与移动反转几乎相同的邻接测试水平,但不受缓存或缓冲的影响。由于单独的写入遍(1.1、1.2)和读取遍(1.4)是针对所有内存完成的,我们可以确保各遍之间的所有缓冲区和缓存都已刷新。选择 20 作为步长是有些任意的。更大的步长可能更有效,但执行时间会更长。选择 20 似乎是速度和彻底性之间的合理折衷。 ## 各测试详细说明 Memtest86+ 执行一系列编号的测试来检查错误。这些测试由测试算法、数据和缓存的组合组成。这些测试的执行顺序安排为使错误能够尽快检测出来。以下是每个测试的说明。 为了允许在 32 位 CPU 上测试超过 4GB 的内存,物理地址范围被分成 1GB 窗口,这些窗口一次一个地映射到虚拟内存窗口中。每个 1GB 窗口可能包含一个或多个连续的内存区域。对于大多数测试,测试依次在每个内存区域上执行。除第一个测试外,所有测试都启用了缓存。 ### 测试 0:地址测试,行走 1,无缓存 在每个内存区域中,使用行走 1 地址模式测试所有地址位。此测试的错误不会对 BadRAM 模式、memmap 区域或坏页区域做出贡献。 ### 测试 1:地址测试,窗口内的自身地址 在每个内存区域中,每个地址写入其自身的地址,然后检查每个地址的一致性。此测试与每个可用的 CPU 顺序执行,无论用户选择何种 CPU 排序模式。 ### 测试 2:地址测试,自身地址 + 窗口 在所有内存区域中,每个地址写入其自身的虚拟地址加上窗口编号(对于 32 位镜像)或自身物理地址(对于 64 位镜像),然后检查每个地址的一致性。这可以捕获在逐个窗口测试时会被遗漏的高阶地址位中的任何错误。此测试与每个可用的 CPU 顺序执行,无论用户选择何种 CPU 排序模式。 ### 测试 3:移动反转,全 1 和全 0 在每个内存区域中,依次对每个模式使用全 1 和全 0 模式的移动反转算法。 ### 测试 4:移动反转,8 位模式 在每个内存区域中,依次对每个模式使用 8 位宽行走 1 和行走 0 模式的移动反转算法。 ### 测试 5:移动反转,随机模式 在每个内存区域中,依次对每个模式使用随机数及其反码模式的移动反转算法。随机数在每次测试通过时都不同,因此多次通过会增加有效性。 ### 测试 6:移动反转,32/64 位模式 在每个内存区域中,依次对每个模式使用 32 位宽(在 32 位构建上)或 64 位宽(在 64 位构建上)行走 1 和行走 0 模式的移动反转算法。与之前的测试不同,模式在每个连续地址上旋转 1 位。 ### 测试 7:块移动,64 次移动 此测试通过使用块移动(movs)指令对内存施加压力,基于 Robert Redelmeier 的 burnBX 测试。 在每个内存区域中,内存用每 8 字节反转一次的移位模式初始化。然后使用 movs 指令移动内存块。移动完成后检查数据模式。因为只有在内存移动完成后才检查数据,所以不可能知道错误发生在哪里。报告的地址仅是针对发现错误模式的位置。因此,此测试的错误不会对 BadRAM 模式、memmap 区域或坏页区域做出贡献。 ### 测试 8:随机数序列 在每个内存区域中,每个地址写入一个随机数,然后检查每个地址的一致性并用原始数据的反码写入,然后再次检查每个地址的一致性。 ### 测试ulo 20,随机模式 在每个内存区域中,依次对每个模式使用随机数及其反码模式的 Modulo-20 算法。随机数在每次测试通过时都不同,因此多次通过会增加有效性。 ### 测试 10:位衰减测试,2 种模式 在所有内存区域中,依次对每个模式,用模式初始化每个内存位置,休眠一段时间,然后检查每个内存位置的一致性。测试使用全 0 和全 1 的模式执行。 ## 已知限制与缺陷 请参阅 GitHub 上的[开放问题](https://github.com/memtest86plus/memtest86plus/issues)和[增强请求](https://github.com/memtest86plus/memtest86plus/discussions)列表。 欢迎提交缺陷报告! ## 代码贡献 欢迎代码贡献,无论是修复缺陷还是进行增强。请参阅 doc 目录中的 README_DEVEL.md 了解一些基本指南。 ## 致谢 Memtest86+ v6.0 基于 Martin Whitaker 开发的 PCMemTest,PCMemTest 基于 Samuel Demeulemeester 开发的 Memtest86+ v5.01,而 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 版的所有功能内容以及大量缺陷修复和重要的代码清理。 * 3.2、3.3 和 3.4 版中硬件检测和报告的重大增强由 Samuel Demeulemeester 提供(来自 Memtest86+ v1.11、v1.60 和 v1.70)。 此外,Memtest86+ 的多项缺陷修复是从 [anphsw/memtest86](https://github.com/anphsw/memtest86) 导入的。
标签:BIOS, GCC编译, LoongArch64, Loongson, Memtest86+, Pentium, UEFI, x86, x86-64, 二进制发布, 代码可维护性, 代码贡献, 低级系统软件, 内存测试, 内存测试哲学, 内存测试算法, 内存诊断工具, 内存错误报告, 内存错误检测, 夜间构建, 客户端加密, 已知限制, 开源工具, 开源硬件工具, 引导加载程序, 引导选项, 独立内存测试, 硬件兼容性, 硬件诊断, 稳定版, 系统稳定性, 系统维护, 键盘选择