AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 908925
Accepted
j3d1H
j3d1H
Asked: 2017-04-26 13:56:10 +0800 CST2017-04-26 13:56:10 +0800 CST 2017-04-26 13:56:10 +0800 CST

如何告诉 ubuntu 不要使用某些内存地址?

  • 772

如果措辞不当,我很抱歉,但我已经在我的一台计算机上进行了内存测试,并且某些内存地址有错误。这是我第一次搜索。如果您需要更多信息,那么我可以提供。

memory-test
  • 4 4 个回答
  • 5051 Views

4 个回答

  • Voted
  1. Best Answer
    heynnema
    2017-04-26T14:05:20+08:002017-04-26T14:05:20+08:00

    如果您查看/etc/default/grub,您会发现一个GRUB_BADRAM=参数,您可以在其中识别哪些坏内存位置存在。

    # Uncomment to enable BadRAM filtering, modify to suit your needs
    # This works with Linux (no patch required) and with any kernel that obtains
    # the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)
    #GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef"
    

    设置好地址后,运行sudo update-grub应用。

    注意:这GRUB_BADRAM 不适用于内核锁定(如果您有安全启动,则会启用)。您可以通过运行检查是否启用了安全启动mokutil --sb-state。


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

    Grub2 中的 BADRAM 设置

    Natty 中的 GRUB2 配置文件有一行用于配置内核坏 ram 排除项。因此,我将假设这是映射出显示错误的内存部分的首选方法。我设置的线是

    GRUB_BADRAM="0x7DDF0000,0xffffc000" 
    

    在我能找到的每个网站上,建议的方法是运行 memtest86 并让它显示 BadRAM 设置。memtest86 给了我一页我必须输入的东西。我可以看到所有地址都在一个 16K 块中,所以我只想映射那个 16K 块停止运行。这是我生成正确条目的方式。

    第一个参数很简单。那是坏内存的基地址。就我而言,我可以看到所有坏地址都大于 0x7DDF0000 且小于 0x7DDF4000。所以,我把 16K 块的开头作为我的起始地址。

    第二个参数是掩码。您将 1s 放在您想要的地址范围共享相同值的位置,并将 0s 放在它会变化的位置。这意味着您需要选择您的地址范围,以便只有低位发生变化。看我的地址,面具的第一部分很容易。你想从 0xffff 开始。对于下一个半字节,我将使用位图进行解释。我希望范围从 0000 到 0011。因此,badram 的掩码将是 1100 或十六进制 c。掩码中的最后 3 个半字节需要全为 0,因为我们想要映射出整个范围。所以,我们得到的总结果是 0xffffc000。

    在 /etc/default/grub 中设置此行后,我运行 sudo update-grub 并重新启动,我的坏内存不再被使用。使用这种方法不需要内核补丁来映射坏内存。

    dmesg您可以通过运行并查找BIOS-provided physical RAM mapor来检查提供的范围是否正确extended physical RAM map:

    [    0.000000] BIOS-e820: [mem 0x000000022a898000-0x000000022a89bfff] unusable
    

    您还可以/proc/iomem以 root 身份检查以查看不可用的范围。


    当然,最好的行动计划是更换有缺陷的 RAM。

    • 8
  2. AmanicA
    2020-04-17T00:56:54+08:002020-04-17T00:56:54+08:00

    我发现对我来说最简单、最可靠的方法是将内核参数memtest=4添加到我的 GRUB 配置中。这会增加几秒钟的启动时间,内核会检查您的 ram,然后将它们标记为对您不利。

    1. sudo nano /etc/default/grub

    2. 更新这一行:

      GRUB_CMDLINE_LINUX_DEFAULT="quiet splash memtest=4"
      
    3. sudo update-grub

    4. reboot

    5. 或者,通过运行检查它是否正常工作dmesg并查看如下日志:

      [    5.043917]   aaaaaaaaaaaaaaaa bad mem addr 0x0000000581a90000 - 0x0000000581a90010 reserved
      

    来源。

    • 6
  3. Erotemic
    2021-07-12T11:29:55+08:002021-07-12T11:29:55+08:00

    为了继续@heynnema 的回答,我编写了一个小的 python 脚本来计算掩码应该是什么。我不确定使用 bin 操作找到最左边的 0 位置的正确方法是什么,所以我使用基于字符串的函数对其进行了破解。但它确实适用于以编程方式查找掩码:

    def find_grub_badram_format(start, stop):
        """
        References:
            https://askubuntu.com/questions/908925/how-do-i-tell-ubuntu-not-to-use-certain-memory-addresses
    
        Example:
            start = 0x7DDF0000
            stop  = 0x7DDF4000 - 1
        """
        import numpy as np
        nbytes = 64
        dtype = np.uint64
        # Starting bad mem address range
        start = dtype(start)
        # Subtract 1 because to make the stop range inclusive instead of exclusive
        stop  = dtype(stop)
    
        def xnor(a, b):
            return ~(a ^ b)
    
        def find_pos_of_leftmost_sig_zero(a, nbytes=64):
            """
            Given a bit string like, we find the position of the first zero bit we
            see coming from the left, such that we can right-bitshift to it to the
    
                011111110110110
                 ^      ^
    
            Example:
                >>> nbytes = 32
                >>> vals = [0b0, 0b1, 0b1111011, 0b1001]
                >>> for a in vals:
                >>>     print('-----')
                >>>     pos0 = find_pos_of_leftmost_sig_one_and_zero(a, nbytes)
                >>>     print(f'a = {a:032b}')
                >>>     print('    ' + ' ' * (nbytes - pos0 - 1) + '^')
                -----
                a = 00000000000000000000000000000000
                                                   ^
                -----
                a = 00000000000000000000000000000001
                                                   ^
                -----
                a = 00000000000000000000000001111011
                                                 ^
                -----
                a = 00000000000000000000000000001001
                                                 ^
            """
            # not really a fast op, but it works well enough There is a semi-corner
            # case at 1 and 0, but it doesnt change how we use it
            binstr = ('{:0' + str(nbytes) + 'b}').format(a)
            try:
                leftmost_one = binstr.index('1')
            except ValueError:
                return 0
            try:
                leftmost_sig_zero = binstr[leftmost_one:].index('0') + leftmost_one
            except Exception:
                return 0
            # Flip string indexes to bit indexes
            sig_zero = nbytes - (leftmost_sig_zero + 1)
            return sig_zero
    
        def find_first_sig_one(a, nbytes=64):
            binstr = ('{:0' + str(nbytes) + 'b}').format(a)
            leftmost_one = binstr.index('1')
            sig_one = nbytes - (leftmost_one + 1)
            return sig_one
    
    
        # Find all the bits in common
        common = xnor(start, stop)
    
        # Find the position of the first zero (non-common bit) we see from the left
        shift0 = find_pos_of_leftmost_sig_zero(common, nbytes) + 1
    
        # Find the number of significant bits in the stop position
        shift1 = find_first_sig_one(stop, nbytes) + 1
    
    
        shift0 = dtype(shift0)
        shift1 = dtype(shift1)
    
        head_mask = (dtype(1) << shift1) - dtype(1)
        tail_mask = ~((dtype(1) << shift0) - dtype(1))
        mask = head_mask & tail_mask
    
        print(f'start  = 0b{start:064b} = 0x{start:016x}')
        print(f'stop   = 0b{stop:064b} = 0x{stop:016x}')
        print(f'common = 0b{common:064b} = 0x{common:016x}')
        print(f'mask   = 0b{mask:064b} = 0x{mask:016x}')
    
        print('--')
        print(f'mask = ' + hex(mask))
    
        badram_format = f'{start:#0{18}x},{mask:#0{18}x}'
        print(badram_format)
        badram_format = f'{start:#x},{mask:#x}'
        print(badram_format)
    

    这导致

    start  = 0b0000000000000000000000000000000001111101110111110000000000000000 = 0x000000007ddf0000
    stop   = 0b0000000000000000000000000000000001111101110111110011111111111111 = 0x000000007ddf3fff
    common = 0b1111111111111111111111111111111111111111111111111100000000000000 = 0xffffffffffffc000
    mask   = 0b0000000000000000000000000000000001111111111111111100000000000000 = 0x000000007fffc000
    --
    mask = 0x7fffc000
    0x000000007ddf0000,0x000000007fffc000
    0x7ddf0000,0x7fffc000
    
    • 0
  4. Marco
    2021-07-17T18:56:53+08:002021-07-17T18:56:53+08:00

    如果您启用了内核锁定(如果您使用安全启动,则默认情况下启用), heynnema 的答案不起作用。

    AmanicA 的回答并没有真正扩展:它会在每次启动时运行测试,从而减慢您的启动时间。

    您可以使用内核 cmdline 参数memmap来保留某些物理内存区域,以便不使用它们。

    有关详细信息,请参阅内核参数。

    例如,memtest86+ 和 linux memtest 发现地址 0x22a89a128 在我的机器上出现故障。

    因此,我在内核 cmdline 中添加了以下行,以禁用故障内存页面周围的 8KiB 内存:

    memmap=16K$0x22a898000

    从物理地址开始保留(这就是$它的用途)16 KiB 的内存0x22a898000。

    我通过在该文件中的变量末尾进行编辑/etc/default/grub和添加,然后运行​​.memmap=16K\\\$0x22a898000GRUB_CMDLINE_LINUX_DEFAULTsudo update-grub

    这\\\是因为 grub 做了一些奇怪的字符转义。

    您可以通过在 dmesg 中查找保留区域或以/proc/iomemroot 身份打开来验证这是否有效:

    # grep 22a89 /proc/iomem
    100000000 - 22a897fff : System RAM
    22a898000 - 22a89bfff : Reserved
    22a89c000 - 4807fffff : System RAM
    
    • 0

相关问题

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve