Pourquoi Linux montre-t-il à la fois plus et less de memory que je ne l'ai physiquement installé?

Je sais au sujet de swap – cette question n'est pas à ce sujet. En dmesg, le kernel Linux (x86-64) me dit à quel point j'ai de la memory:

[ 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 par mes calculs, je pense que je devrais avoir exactement 4 * 1024 * 1024 = 4194304k RAM. Ce qui est beaucoup plus petit que le deuxième chiffre dans la ligne dmesg ci-dessus!

Qu'est-ce qui se passe avec toutes ces différentes figures?

Par ailleurs, uname -a sorties:

 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 

Vous devriez lire les valeurs dmesg "Memory Akb / Bkb available" comme suit:

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

Cela provient 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 memory physique, gérée par le kernel, qui n'est pas actuellement utilisée. max_pfn est le numéro d'image le plus élevé (le décalage PAGE_SHIFT le convertit en kb). Le nombre de trames de page le plus élevé peut être (beaucoup) plus élevé que ce à quoi vous pouvez vous attendre – le mappage de memory effectué par le BIOS peut contenir des trous.
La quantité de ces trous est suivie par la variable absent_pages , affichée en tant que kB absent . Cela devrait expliquer la plupart de la différence entre le deuxième nombre dans la sortie "disponible" et votre RAM actuelle installée.

Vous pouvez grep pour BIOS-e820 dans dmesg pour "voir" ces trous. La carte memory y est affichée (en haut à droite de la sortie dmesg après le démarrage). Vous devriez être capable de voir à quelles adresses physiques vous avez une RAM réelle et utilisable.
(Les autres bizarreries x86 et les zones de memory réservées représentent probablement le rest – je ne connais pas les détails.)

MemTotal dans /proc/meminfo indique la RAM disponible pour l'utilisation. A la fin de la séquence de démarrage, le kernel libère datatables init il n'a plus besoin, de sorte que la valeur rapscope dans /proc/meminfo peut être un peu plus élevée que celle que le kernel imprime pendant les parties initiales de la séquence de démarrage .

( meminfo utilise indirectement totalram_pages pour cet affichage.) Pour x86_64, ceci est aussi calculé dans arch/x86/mm/init_64.c via free_all_bootmem() qui est lui-même dans mm/bootmem.c pour les kernelx non-NUMA.