alloc en mode réel (i386)

Le
Cyrille Szymanski
Bonjour,

je cherche à allouer un bloc mémoire et obtenir son
adresse en mode réel pour passer cette adresse à une
interruption vm86 sous FreeBSD (i386_vm86(2)).

J'ai pensé à deux méthodes :
1_ Appeler malloc() normalement, récupérer la LDT et
faire le calcul moi-même. Mais a mon avis l'adressage
virtuel fera que c'est pas possible.
2_ Utiliser mmap() et écrire moi même un malloc pour
allouer/déallouer les blocs.

Y a-t-il une méthode plus simple ?

--
cns
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
jmz
Le #639253
Cyrille Szymanski
Bonjour,

je cherche à allouer un bloc mémoire et obtenir son
adresse en mode réel pour passer cette adresse à une
interruption vm86 sous FreeBSD (i386_vm86(2)).

J'ai pensé à deux méthodes :
1_ Appeler malloc() normalement, récupérer la LDT et
faire le calcul moi-même. Mais a mon avis l'adressage
virtuel fera que c'est pas possible.
2_ Utiliser mmap() et écrire moi même un malloc pour
allouer/déallouer les blocs.

Y a-t-il une méthode plus simple ?


Quelque chose comme ça : ?

buf = vm_page_alloc_contig (size, 0x100000, 0x1000000-1, PAGE_SIZE);
if (!buf) {
device_printf (dev, "can't allocate %dK of physical memoryn", size/1024);
goto failure;
}
buf = vtophys (buf);
device_printf (dev, "%dK of physical memory allocated (address=0x%x)n",
size/1024, buf);

Jean-Marc
--
Jean-Marc Zucconi -- PGP Key: finger [KeyID: 400B38E9]

Cyrille Szymanski
Le #639252
On 2004-04-11, Jean-Marc Zucconi
je cherche à allouer un bloc mémoire et obtenir son
adresse en mode réel pour passer cette adresse à une
interruption vm86 sous FreeBSD (i386_vm86(2)).


Quelque chose comme ça : ?

buf = vm_page_alloc_contig (size, 0x100000, 0x1000000-1, PAGE_SIZE);
if (!buf) {
device_printf (dev, "can't allocate %dK of physical memoryn", size/1024);
goto failure;
}
buf = vtophys (buf);
device_printf (dev, "%dK of physical memory allocated (address=0x%x)n",
size/1024, buf);


C'est pas mal, il me reste juste à convertir cette adresse en segment:offset
et le tour est joué.

Par contre je ne trouve pas les pages man de vm_page_alloc_contig et vtophys
et il me semble que c'est parce qu'elles ont été bannies depuis la création
de bus_dma.

Est-ce aussi simple à faire avec bus_dma ? J'ai survolé l'article
Jason R. Thorpe, "A Machine-Independent DMA Framework for NetBSD"
mais il n'est pas donné de code source, je ne peux pas me rendre compte
de ce que ça donne.

Merci pour la réponse.
--
cns


pornin
Le #639250
According to Cyrille Szymanski
1_ Appeler malloc() normalement, récupérer la LDT et
faire le calcul moi-même. Mais a mon avis l'adressage
virtuel fera que c'est pas possible.


Je dis ça un peu hors-contexte, mais il s'avère que le i386 possède
trois "modes", qui sont le mode réel, le mode protégé et le mode vm86.
Le mode vm86 est une émulation du mode réel, avec le mode protégé
toujours actif en dessous, et notamment la pagination. Ce qui veut dire
que les adresses virtuelles restent inchangée au passage en vm86.

À noter cependant que la pagination (i.e., la correspondance entre les
adresses virtuelles et les adresses réelles) change à chaque commutation
entre deux processus.


--Thomas Pornin

Cyrille Szymanski
Le #639000
Je dis ça un peu hors-contexte, mais il s'avère que le i386 possède
trois "modes", qui sont le mode réel, le mode protégé et le mode vm86.
Le mode vm86 est une émulation du mode réel, avec le mode protégé
toujours actif en dessous, et notamment la pagination. Ce qui veut dire
que les adresses virtuelles restent inchangée au passage en vm86.


Pour les pointeurs < 2^20 je peux donc calculer une adresse
16:16 en faisant un segment = (ptr >> 8), offset = ptr & 0xF.

Pour allouer de la mémoire en dessous de la limite des 1M, j'ai essayé
d'utiliser mmap :

fd_zero = open("/dev/zero", O_RDONLY);

m = mmap((void *)0x10000, 0x10000,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE, fd_zero, 0);

et ensuite je passe l'adresse 1000:0000 au gestionnaire d'interruption
appelé en vm86 mais cela génère une page fault (alors que l'écriture/
lecture en mode protégé fonctionne).

C'est pas comme-ça qu'il faut faire ?

Merci pour votre aide.
--
cns

Publicité
Poster une réponse
Anonyme