Pourquoi Linux affiche-t-il à la fois plus et moins de mémoire que ce que j'ai physiquement installé?

11

Je connais le swap - cette question n'est pas à ce sujet. Dans dmesg, le noyau Linux (x86-64) me dit ceci sur la quantité de mémoire dont j'ai:

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

cat /proc/meminfo me dit que j'ai

MemTotal:        3910472 kB

Et d'après mes calculs, je pense que je devrais avoir exactement 4 * 1024 * 1024 = 4194304k RAM. Ce qui est bien plus petit que le deuxième chiffre de la ligne dmesg ci-dessus!

Qu'y a-t-il avec toutes ces différentes figures?

Soit dit en passant, les uname -asorties:

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
Robin Green
la source

Réponses:

20

Vous devez lire les dmesgvaleurs "Mémoire Akb / Bkb disponible" comme:

Il y a A disponible pour utilisation en ce moment, et le nombre de cadres de page le plus élevé du système multiplié par la taille de la page est B.

Cela vient de 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()renvoie la quantité de mémoire physique, gérée par le noyau, qui n'est pas actuellement utilisée. max_pfnest le numéro de cadre de page le plus élevé (le PAGE_SHIFTdécalage le convertit en Ko). Le numéro de cadre de page le plus élevé peut être (beaucoup) plus élevé que ce à quoi vous pourriez vous attendre - le mappage de mémoire effectué par le BIOS peut contenir des trous.
La quantité absorbée par ces trous est suivie par la absent_pagesvariable, affichée sous la forme kB absent. Cela devrait expliquer la majeure partie de la différence entre le deuxième nombre dans la sortie "disponible" et votre RAM réelle installée.

Vous pouvez grep BIOS-e820dans dmesgces trous « voir ». La carte mémoire y est affichée (juste en haut de la dmesgsortie après le démarrage). Vous devriez pouvoir voir à quelles adresses physiques vous disposez d'une RAM réelle et utilisable.
(Les autres bizarreries x86 et les zones de mémoire réservées expliquent probablement le reste - je ne connais pas les détails là-bas.)

MemTotalin /proc/meminfoindique que la RAM est disponible. À la fin de la séquence de démarrage, le noyau libère les initdonnées dont il n'a plus besoin, de sorte que la valeur indiquée dans /proc/meminfopourrait être un peu plus élevée que ce que le noyau imprime pendant les premières parties de la séquence de démarrage.

( meminfoutilise indirectement totalram_pagespour cet affichage. Pour x86_64, cela est également calculé arch/x86/mm/init_64.cvia free_all_bootmem()ce qui est lui-même mm/bootmem.cpour les noyaux non NUMA.)

Tapis
la source