Le Mode Unreal

À l’origine des processeurs x86, le 8086 avait une adresse mémoire de 20 bits (0x0 à 0xFFFFF), il était donc limité a 1Mo de RAM (2^20=1048576). Mais l’espace d’adressage étant légèrement supérieur (0xFFFF:0xFFFF = 0x10FFEF), le 20ème bit était tout simplement oublié. Cela veut dire qu’au lieu d’acceder à l’adresse 0x10FFEF (21 bits) on accede à l’adresse 0xFFEF (20 bits). Cela s’appelle le wrap-arround. Les générations suivantes avaient plus de RAM, le wrap-around devenait donc inutile. Mais voilà le problème: certain programmes on besoin du wrap-around pour fonctionner ! Et comme la devise d’Intel c’est “100% compatible”, le wrap-around garde donc sa place. Mais ne vous inquietez pas, le 20ème bit pourra être activé grâce a l’A20 Gate. Le seul problème c’est qu’il y a plusieurs façons de l’activer et cela dépend de votre machine. Voici trois méthodes que je vais vous présenter rapidement, elles devraient fonctionner sur la plupart des machines actuelles. La première est la plus vielle et la plus lente, on passe par le controlleur clavier (8042).

in al, 0x64
test al, 2
jnz $-4

mov al, 0xd1
out 0x64, al


in al, 0x64
test al, 2
jnz $-4


mov al, 0xdf
out 0x60, al

La deuxième est beaucoup plus rapide, on passe par le System Control Port A

in al, 0x92
or al, 0x02
out 0x92, al

La troisième est plus simple, on passe par le BIOS.

mov ax, 0x2401
int 0x15

L’A20 Gate est activé on peut donc acceder à ce fameux 20ème bit ! ce qui fait... 64 Ko en plus !? Et bien oui, c’est tout ! Mais alors comment acceder a toute la RAM ? Tout d’abord la limite des 4 Go est apparût sur le 386 qui possédait une adresse mémoire de 32 bits (le 286 n’en avait que 24). Et pour rester compatible (encore) le processeur posséde maintenant différent modes de fonctionnement, le mode réel et le mode protégé. Le mode réel est compatible avec le 8086, et c’est le mode actif à chaque démarrage. Le mode protégé sert à la simplication de la programmation et à la protection materielle des systemes multi-tâches (d’ou son nom). Le seul interet de ce mode (pour nous) est de pouvoir modier les registres de segment en entier grâce a des déscripteurs de segment qui sont répertorié dans la GDT (Global Descriptor Table). La petite astuce tient dans le fait que lorsque l'on revient en mode réel les registres de segment ne sont pas modié. On peut donc utiliser toute la mémoire en mode réel ! La méthode est de passer en mode protégé, modier les registres de segment de façons à avoir accé a toute la RAM, et revenir en mode réel. Et nous voilà dans le mode unreal ! La première étape est donc de dire au processseur ou se trouve la GDT, il faut calculer son adresse linéaire.

xor eax, eax
mov ax, cs
shl eax, 4
add [gdt+2], eax

On la charge.

lgdt [gdt]

On passe en mode protégé.

mov eax, cr0
inc eax
mov cr0, eax

Maintenant on peut modier entiérement les registres de segment.

mov bx, 0x8
mov ds, bx
mov es, bx
mov fs, bx
mov gs, bx

On reviens en mode réel.

dec eax
mov cr0, eax

Et voici notre GDT, elle contient deux descripteurs de segment:
- Le descripteur null est obligatoire, mais étant ignoré par le processeur vous pouvez l'utiliser comme pointeur.
- Le descripteur de donné.

GDT

; 0x0 Descripteur null (pointeur)


dw GDT.end-GDT-1
dw GDT
dd 0

; 0x8 Descripteur de segment de donnée

dw 0xFFFF
dw 0
db 0
db 10010010b
db 10001111b
db 0

.end

Nous avons maintenant les registres DS, ES, FS, GS qui pointe sur un segment de donnée de 4 Go. Pour les curieux sachez que je ne présente ici qu’une infime partie du mode protégé, pour plus d’information reportez vous au manuel Intel.

par Adrien S. Gallouët (juin 2003)