Как мне сказать 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)
- судо нано / и т.д. / по умолчанию / grub
- обновите эту строку:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash memtest=4"
- sudo update-grub
- перезагрузка
- при желании проверьте, что он работает, запустив
dmesg
и посмотрите логи вроде этого:[ 5.043917] aaaaaaaaaaaaaaaa bad mem addr 0x0000000581a90000 - 0x0000000581a90010 reserved
Ответ 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