Как мне сказать Ubuntu не использовать определенные адреса памяти?

Извините, если это плохо сформулировано, но я провел тест памяти на одном из моих компьютеров, и на некоторых адресах памяти есть ошибки. Это первый раз, когда я искал. Если вам нужна дополнительная информация, я могу ее предоставить.

4 ответа

Решение

Если вы посмотрите в /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"

Взято с https://help.ubuntu.com/community/BadRAM...

Настройка BADRAM в Grub2

Конфигурационный файл GRUB2 в Natty содержит строку для настройки исключений из ядра. Итак, я предполагаю, что это предпочтительный способ отображения раздела памяти, который показывает ошибки. Линия, которую я установил, была

GRUB_BADRAM="0x7DDF0000,0xffffc000" 

Предлагаемый способ на каждом веб-сайте, который я мог найти, состоял в том, чтобы установить это, запустив memtest86 и позволив ему показать вам настройки BadRAM. memtest86 дал мне страницу, в которую я должен был войти. Я мог видеть, что все адреса были в одном блоке 16K, поэтому я просто хотел отобразить этот блок 16K из строя. Вот как я сгенерировал правильную запись.

Первый параметр прост. Это базовый адрес плохой памяти. В моем случае я мог видеть, что все плохие адреса были больше, чем 0x7DDF0000 и меньше, чем 0x7DDF4000. Итак, в качестве начального адреса я взял начало блока 16К.

Второй параметр - это маска. Вы ставите 1, где диапазон адресов, который вы хотите, имеет те же значения, и 0, где он будет меняться. Это означает, что вам нужно выбрать диапазон адресов так, чтобы менялись только младшие биты. Глядя на мой адрес, первая часть маски проста. Вы хотите начать с 0xffff. Для следующего куска я объясню с помощью битовых карт. Я хочу в диапазоне от 0000 до 0011. Таким образом, маска для бадрама будет 1100 или гекс с. Последние 3 полубайта должны быть все 0 в маске, так как мы хотим, чтобы весь диапазон отображался. Итак, мы получаем общий результат 0xffffc000.

После установки этой строки в / etc / default / grub я запустил sudo update-grub и перезагрузился, и моя плохая память больше не использовалась. Никаких патчей ядра не требуется для определения плохой памяти с помощью этого метода.


Конечно, лучшим планом действий было бы заменить неисправную оперативную память.

Я нашел для себя самый простой и надежный способ - добавить параметр ядра memtest=4в мою конфигурацию Grub. Это добавляет пару секунд к загрузке, когда ядро ​​проверяет ваш баран, а затем помечает их как плохие для вас \o/ (слава Богу, поскольку я не могу заменить свой баран в этой блокировке Covid19)

  1. судо нано / и т.д. / по умолчанию / grub
  2. обновите эту строку:
    GRUB_CMDLINE_LINUX_DEFAULT="quiet splash memtest=4"
  3. sudo update-grub
  4. перезагрузка
  5. при желании проверьте, что он работает, запустив dmesg и посмотрите логи вроде этого:
    • [ 5.043917] aaaaaaaaaaaaaaaa bad mem addr 0x0000000581a90000 - 0x0000000581a90010 reserved

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

Ответ heynnema не работает, если у вас включена блокировка ядра (которая включена по умолчанию, если вы используете безопасную загрузку).

Ответ AmanicA на самом деле не масштабируется: он будет запускать тест при каждой загрузке, замедляя время загрузки.

Вы можете использовать параметр командной строки ядра memmapзарезервировать определенные области физической памяти, чтобы они не использовались.

Подробности смотрите в параметрах ядра .

Например, memtest86+ и memtest для Linux обнаружили, что адрес 0x22a89a128 на моей машине неверен.

Поэтому я добавил следующую строку в свою командную строку ядра, чтобы отключить 8 КБ оперативной памяти вокруг неисправной страницы оперативной памяти:

memmap=16K$0x22a898000

Какие резервы (это то, что $для) 16 КБ памяти, начиная с физического адреса 0x22a898000.

Я сделал это, отредактировав /etc/default/grubи добавление memmap=16K\\\$0x22a898000в конце GRUB_CMDLINE_LINUX_DEFAULTпеременная в этом файле, а затем запустив sudo update-grub.

The \\\это потому, что grub делает какой-то странный экранирующий символ.

Вы можете убедиться, что это работает, найдя зарезервированные регионы либо в dmesg, либо открыв /proc/iomemкак корень:

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

Чтобы продолжить ответ @heynnema, я написал небольшой скрипт на Python, чтобы вычислить, какой должна быть маска. Я не был уверен, как правильно определить положение самого левого значащего 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
Другие вопросы по тегам