Почему Linux показывает больше и меньше памяти, чем я установил физически?

11

Я знаю о свопе - этот вопрос не об этом. В dmesg ядро ​​Linux (x86-64) сообщает мне, сколько у меня памяти:

[    0.000000] Memory: 3890880k/4915200k available (6073k kernel code, 861160k absent, 163160k reserved, 5015k data, 1596k init)

cat /proc/meminfo говорит мне, что у меня есть

MemTotal:        3910472 kB

И по моим подсчетам, я думаю, что у меня должно быть точно 4 * 1024 * 1024 = 4194304k RAM. Это намного меньше, чем вторая цифра в строке dmesg выше!

Что со всеми этими разными фигурами?

Кстати, uname -aвыводы:

Linux pavilion 3.2.2-1.fc16.x86_64 #1 SMP Thu Jan 26 03:21:58 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
Робин Грин
источник

Ответы:

20

Вы должны прочитать dmesgзначения «Память Akb / Bkb доступно» как:

Сейчас доступно для использования A, а максимальный номер фрейма страницы системы, умноженный на размер страницы, равен B.

Это из arch/x86/mm/init_64.c:

printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, "
                 "%ldk absent, %ldk reserved, %ldk data, %ldk init)\n",
                 nr_free_pages() << (PAGE_SHIFT-10),
                 max_pfn << (PAGE_SHIFT-10),
                 codesize >> 10,
                 absent_pages << (PAGE_SHIFT-10),
                 reservedpages << (PAGE_SHIFT-10),
                 datasize >> 10,
                 initsize >> 10);

nr_free_pages()возвращает объем физической памяти, управляемой ядром, который в данный момент не используется. max_pfnявляется самым большим номером фрейма страницы ( PAGE_SHIFTсдвиг преобразует его в КБ). Максимальный номер кадра страницы может быть (намного) больше, чем вы могли ожидать - отображение памяти, выполненное BIOS, может содержать дыры.
Сколько занимают эти дыры, отслеживается absent_pagesпеременной, отображаемой как kB absent. Это должно объяснить большую часть разницы между вторым числом в «доступном» выводе и вашей фактической установленной оперативной памятью.

Вы можете вычленить для BIOS-e820в dmesg«видеть» эти отверстия. Там отображается карта памяти (справа вверху dmesgпосле загрузки). Вы должны видеть, по каким физическим адресам у вас есть реальная, полезная оперативная память.
(Остальные причуды x86 и зарезервированные области памяти, вероятно, составляют остальное - я не знаю подробностей там.)

MemTotalin /proc/meminfoуказывает ОЗУ, доступную для использования. В самом конце последовательности загрузки ядро ​​освобождает initданные, которые ему больше не нужны, поэтому значение, указанное в отчете, /proc/meminfoможет быть немного выше, чем то, что ядро ​​выводит во время начальных частей последовательности загрузки.

( meminfoиспользуется косвенно totalram_pagesдля этого дисплея. Для x86_64 это arch/x86/mm/init_64.cтоже рассчитывается, через free_all_bootmem()которое само используется mm/bootmem.cдля ядер, отличных от NUMA.)

Мат
источник