2017-08-07 7 views

Répondre

3

Tout simplement, vous ne pouvez pas.

Les champs mem_lower et mem_upper sont des champs obsolètes, se référant aux conventional memory et extended memory.
Citant le specifications:

Si bit 0 dans le mot flags est défini, alors les champs mem_* sont valides.
mem_lower et mem_upper indiquent la quantité de mémoire inférieure et supérieure, respectivement, en kilooctets kibibytes.

La mémoire inférieure commence à l'adresse 0 et la mémoire supérieure commence à l'adresse 1 mégaoctet mebibyte. La valeur maximale possible pour la mémoire inférieure est 640 kilooctets kibibytes.

La valeur renvoyée pour la mémoire supérieure correspond au maximum à l'adresse du premier trou de mémoire supérieur moins 1 mégaoctet mebibyte. Ce n'est pas garanti d'être cette valeur.

Les deux principaux aspects de cet extrait sont:

  1. Le champ flags doit être testé avant d'accéder aux mem_* champs.
  2. Les champs mem_lower et mem_upper traitent très mal les trous de mémoire. En particulier, mem_upper maintient la taille du premier bloc continu de mémoire étendue jusqu'au premier trou.

Le deuxième point est suffisamment important pour mériter une discussion plus approfondie.
Alors que la mémoire elle-même est accessible, au niveau de contrôleur de mémoire , en tant que bloc continu, il n'est pas continu au niveau du sous-système de mémoire (ce qui était autrefois le north-bridge et est maintenant uncore).
Le sous-système de mémoire crée trous dans la plage d'adresses continue affectée à la mémoire soit simplement en ne récupérant pas des sous-plages spécifiques - gaspillant ainsi cette mémoire - soit en décalant les sous-plages à des adresses plus élevées.

Les raisons de ce comportement apparemment étrange ont leurs racines profondes dans l'évolution historique de l'IBM PC.
Une discussion complète est hors sujet, mais une version courte peut être présentée. Initialement, IBM réservait les 640 Ko de l'espace d'adressage de 1 Mo pour la mémoire conventionnelle et les 384 Ko restants pour le mappage des ROM, y compris la ROM du BIOS.
Notez que le contrôleur de mémoire ne doit pas répondre aux accès en lecture/écriture au-dessus de la 640 Ko pour qu'ils puissent accéder aux ROM.Lorsque la barrière 1MiB a été brisée (y compris HMA à volonté), la plage de 640KiB à 1MiB n'a pas pu être utilisée pour des raisons de compatibilité ascendante. Cela a créé le premier trou: le trou standard.
Le 286 avait seulement un bus d'adresse de 24 bits, donc un espace d'adresse de 16 Mo.
Dans le même temps, le ISA bus avait déjà gagné contre le MCA bus et a eu lieu dans le matériel compatible IBM PC.
Certaines cartes d'extension ISA sont livrées avec des ROM d'extension et le trou standard est épuisé, un trou de 1 Mo est réservé à la fin de l'espace d'adressage de 16 Mo.
J'appelle ce trou le ISA hole.
À peu près la même chose s'est produite avec PCI (e) lors de la transition de systèmes 32 bits à 64 bits générant le PCI hole.

En plus de ces trous, il existe des plages de mémoire qui sont en lecture/écriture mais qui contiennent des informations précieuses présentées par le BIOS - à savoir le ACPI tables.
Ces plages ne peuvent pas être écrasées par le système d'exploitation et doivent donc lui être signalées.

Tout cela a abouti à la e820 service qu'au lieu de retourner la taille de la mémoire (qui, à la lumière de la discussion ci-dessus fait pas de sens), elle retourne une carte mémoire fait des gammes avec leur type (disponible, réservé, reclaimable , mauvais, NVS).

Cela se reflète également dans les domaines de la structure Grub multiboot_info_tmmap_* que vous devez utiliser à la place du mem_lower et mem_upper comme indiqué dans le OSDev wiki.


Le DIMMs sont accessibles avec un rang, la banque, la colonne et le numéro de rangée mais le contrôleur de mémoire, généralement cet adressage linéaire et continue.