Posts Tagged ‘BadRAM’

memtest86+与BadRAM使用

June 28th, 2015

一般情况下,DRAM的损坏是永久性的损坏,这个时候我们有三种方式解决这个问题:

  1. 买新的内存条
  2. 在kernel启动时加入mem参数,限制当前mem的使用,比如当前内存2GB,在800M地方,内存存在永久故障区域,那么我们可以在kernel的启动参数加入mem=780M,这样就可以限制当前内核分配800M的内存区域而触发MCE。但是这个也有一个明显的缺点:因为这个坏点导致大部分内存无法使用
  3. 在kernel启动加入badram 0x01000000,0xfffffffc即可。

我们这里使用第三种方式来绕过当前的内存坏块,而达到省钱的目的!badram 第一个参数 是出错的物理基地址,第二个参数是mask,来用标示这个掩码。当我们使用memtest86+测试出当前的出错内存物理地址,然后将这个错误地址加入到kernel 参数中即可。

其中memtest86+是一款离线内存检测工具,可以检测内存中的坏页。

下面我们来实验一下,比如当前系统没有出现内存坏块,那么使用iomem参看当前物理内存地址的分布:

00000000-00000fff : reserved
00001000-0009f3ff : System RAM
0009f400-0009ffff : reserved
000a0000-000bffff : PCI Bus 0000:00
000c0000-000dffff : PCI Bus 0000:00
  000c0000-000c7fff : Video ROM
  000cc000-000cd7ff : Adapter ROM
000e0000-000effff : pnp 00:08
000f0000-000fffff : reserved
  000f0000-000fffff : System ROM
00100000-7f6dffff : System RAM
  01000000-017b9cc4 : Kernel code
  017b9cc5-01d1e8ff : Kernel data
  01e86000-01fc8fff : Kernel bss
....

当我们在grub中加入badram 0x01000000,0xfffffffc参数,也就意味着Kernel代码区的地址出现错误,而且错误大小是2bit,这个时候我们重新启动,再查看当前系统物理内存分布,我们会发现:

01000000-010003ff : RAM buffer
01000400-7f6dffff : System RAM
  02000000-027b9cc4 : Kernel code
  027b9cc5-02d1e8ff : Kernel data

kernel 的代码段避过了问题内存区域,我们查看__pa(x)最终调用__phys_addr_nodebug,而其中phys_base则是在real_mode下面被调用。

static inline unsigned long __phys_addr_nodebug(unsigned long x)
{
    unsigned long y = x - __START_KERNEL_map;

    /* use the carry flag to determine if x was < __START_KERNEL_map */
    x = y + ((x > y) ? phys_base : (__START_KERNEL_map - PAGE_OFFSET));

    return x;
}

22996709_13505212884HWu

Real-mode code 在X+0x8000开始,X就是badram传入的offset!

 

 

参考:

http://ubuntuforums.org/archive/index.php/t-1689890.html

http://ubuntuforums.org/showthread.php?t=2278744

https://help.ubuntu.com/community/BadRAM#BADRAM_setting_in_Grub2

http://blog.chinaunix.net/uid-22996709-id-3376998.html