Précédent   Forum des professionnels en informatique > Autres langages > Assembleur > x86 32-bits / 64-bits
x86 32-bits / 64-bits Architectures x86 32/64 bits et leurs outils (assembleurs, debuggers, émulateurs...)
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 03/02/2012, 19h34   #1
Candidat au titre de Membre du Club
 
Inscription : mars 2006
Messages : 100
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 100
Points : 12
Points : 12
Par défaut mode vesa, graphique, texte, les 2(mais comment faire)

Bonjour à vous tous !!!

Ayant enfin réussis a dessiner a l'écran(pour le moment juste un écran bleu ou violet etc ^^), plusieurs problème se pose. Comment utiliser les modes textes ^^. La première solution serait de "prendre un second mode" et de l'utiliser en mode texte, cela ne me semble pas bon car "short" au niveau du bootloader, quoi que ça doit passer je pense, c'est surtout car je n'ai rien trouver pour l'affichage du texte en vesa ^^.,si vous trouvez, je serais évidemment preneur ^^.

La seconde solution serait de dessiner les caractères a l'écran, bonne, mais en fait mauvaise idée car cela ne m'intéresse pas de devoir dessiner tous les caractères moi même.

Troisième solution, la meilleure celon moi, mais qui ne fonctionne pas, et c'est d'ailleurs pour ça que je viens vous voir. Passer en mode réel, appeler l'interruption 0x10 fonction 00 pour repasser en mode 0x03 qui est le mode d'affichage de base, enfin repasser en mode protégé puis ensuite d'écrire en 0xB8000. Mais évidemment, ça ne fonctionne pas comme prévu ^^.

Le kernel, je pense que c'est le plus important
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[bits 32]
 
org 0x1000
 
jmp _start
_start:
 
	;On passe en mode réel et on active les interrupt
	mov eax, cr0
	and eax, 0xFE
	mov cr0, eax
 
	sti
 
	call switch
 
	cli	
	mov eax, cr0
	or	eax, 1
	mov cr0, eax
 
	mov byte [0xb8000], 'B'
	mov byte [0xb8001], 0b00001111
 
	end : 
	jmp end
 
	[bits 16]
;Permet le changement de mode
;0x3 = mode texte
switch:
	mov ax, 0x03
	int 0x10
 
	ret
Et le bootloader si il vous intéresse, il ne fait que charger la GDT et le mode vesa 118 (1024 * 768), vous pouvez changer ^^.

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
%define BASE    0x100  ; 0x0100:0x0 = 0x1000
%define KSIZE   50     ; nombre de secteurs a charger
 
[BITS 16]
[ORG 0x0]
 
jmp start
start:
 
	;initialisation des segments en 0x07C0
    mov ax, 0x07C0
    mov ds, ax
    mov es, ax
 
	;Initialisation de la pile(F000h - 8000h) = 7000h
    mov ax, 0x8000    
    mov ss, ax
    mov sp, 0xF000
 
	;On récupère l'unité de boot utiliser
	;Disque dur? Disquette?
    mov [bootdrv], dl
 
	;charger le noyau
    xor ax, ax
    int 0x13
 
	;On sauvegarde es
    push es
 
	;On récupère l'adresse du début du kernel
    mov ax, BASE
    mov es, ax
    mov bx, 0
 
	;On récupère la fonction et le nombre de secteur a charger
    mov ah, 2
    mov al, KSIZE
 
	;On indique les cylindres et a partir de quel secteur on charge
    mov ch, 0
    mov cl, 2
 
	;On indique a partir de quel tête et quel unité de disque
    mov dh, 0
    mov dl, [bootdrv]
    int 0x13
 
	;On restaure es
    pop es
 
	;initialisation du pointeur sur la GDT
	;Calcul de la limite de la GDT (fin - début)
    mov ax, gdtend
    mov bx, gdt
    sub ax, bx
    mov word [gdtptr], ax
 
	;Calcul de l'adresse linéaire de la GDT
	mov eax, 0x7C00
	add eax, gdt
	mov dword [gdtptr + 2], eax
 
 
	;Initialisation du mode Vesa
	mov	ax, 0x4F01
	mov	cx, 0x118  ;pour le mode 118h
	mov	di, info_mode  ;pointe sur une structure
	int	0x10
 
	;On récupère l'adresse du LFB, et on le met dans son descripteur
	;C'est a dire dans la GDT
 
	;Le segment est comme ceci "en gros" 	offset  : segment
	;Au lieu de:							segment : offset
 
	mov ax, [PhysBasePtr] 		;"Offset" = bits de poid faible
	mov [gdt_lfb + 2], ax		;Les 2 premiers octet de la base
 
	mov ax, [PhysBasePtr + 2]	;"Segment" = bits de poid fort
 
	mov [gdt_lfb + 4], al 		;3ème octet de la base
	mov [gdt_lfb + 7], ah 		;4ème octet de la base
 
	mov	ax, 0x4F02
	mov	bx, 0x4118			;0x4000 : On met le bit 14 a 1, mode 118
	int	0x10
 
	;passage en modep
    cli              ;Annule les interruptions
    lgdt [gdtptr]    ;charge la gdt
    mov eax, cr0
    or  ax, 1
    mov cr0, eax     ;On met le bit de poid faible de CR0 a 1
 
	;On vide le cache interne
    jmp next
	next:
 
	;Et on réinitialise les segments
	;Les segments de données
	;0x10 = descripteur de segment de données
    mov ax, 0x10        
    mov ds, ax
    mov fs, ax
    mov gs, ax
    mov es, ax
    mov ss, ax
    mov esp, 0x9F000
 
	;Réinitialise le segment de code (0x8) et "jump" vers le kernel
    jmp dword 0x8:0x1000
 
;Les Variables
;--------------------------------------------------------------------
bootdrv:  db 0
;--------------------------------------------------------------------
 
;====================================================================
;							LA GDT
;------------------------------------------------------------------------------
;							Descripteur
 
;	BASE 31:24	||	G;DB;0;1;LIM19:16 	|| P;DPL(2);S;TYPE(4) || BASE 23 :16
;			BASE 15 : 0					||					LIMITE 15:0
 
;	G 	= granularité = 	si 1, limite = nombre de page de 4ko,
;							si 0, limite = nombre d'octet
 
;	DB 	= taille des instructions et des données : 1 pour 32 bits
;	P  	= Segment en mémoire physique : 1
;	DPL = 2bits, indique le niveau de privilège, 0 = super utilisateur
;	S	= 1 descripteur de segment, 0 pour descripteur de système
;	TYPE= 4 bits, indique le type de segment, premier bit a 0(données) 1(code)
;------------------------------------------------------------------------------
 
gdt:		;Pointeur sur le début du segment de la GDT
gdt_NULL :						;Déscripteur "NULL"
    db 0, 0, 0, 0, 0, 0, 0, 0
 
gdt_cs:							;Descripteur de code
    db 	0xFF, 0xFF, 			;limite
	db	0x0, 0x0, 0x0, 			;base
	db	10011011b, 11011111b, 	;type
	db	0x0						;base
 
gdt_ds:							;Descripteur de segment
 
    db	0xFF, 0xFF,				;limite
	db	0x0, 0x0, 0x0, 			;base
	db	10010011b, 11011111b, 	;type
	db	0x0						;Base
 
gdt_lfb :						;Descripteur du LFB("écran")
	db 	0xFF, 0xFF,				;limite
	db	0x0, 0x0, 0x0,			;base ( modifier dans le code )
	db	10010011b, 11011111b,	;type( grosse ressemblance au desc de donnée )
	db	0x0						;base ( modifier dans le code )
 
gdtend:;Pointeur sur la fin du segment de la GDT
 
;--------------------------------------------------------------------
gdtptr:
    dw 0  ; limite
    dd 0  ; base
;--------------------------------------------------------------------
 
;====================================================================
 
info_mode:
	FlagMode		dw	0; // Flag du mode video concerne
	FlagW1			db	0;   // Flag de la premiere fenetre d'acces
	FlagW2			db	0;   // Flag de la deuxieme fenetre d'acces
	Gran			dw	0;     // Granularite en Ko
	WTaille			dw	0;  // Taille des deux fenetres d'acces
	W1Seg			dw	0;    // Segment de la premiere fenetre
	W2Seg			dw	0;    // Segment de la deuxieme fenetre
	Foncp			dd	0;   // Offset de la fonction Bank switch
	ByteRes			dw	0;  // Nb d'octets occupés par une ligne de pts
	XRes			dw	0;     // Resolution en X pts/carac
	YRes			dw	0;     // Resolution en Y pts/carac
	XCar			db	0;     // Largeur caractere en pts
	YCar			db	0;     // Longueur caractere en pts
	NPlan			db	0;    // Nombre de plans de bits
	BPpix			db	0;    // Nombre de bits par pixels
	NBank			db	0;    // Nombre de bank memoire
	MModel			db	0;   // Modele memoire
	BTaille			db	0;  // Taille des banks memoires
	IPage			db	0;    // Nombre d'image page
	Reserve			db	0;  // Toujours à 1
	;  // VBE 1.2 Extensions
	RedMaskSize		db	0;
	RedFieldPosition	db	0;
	GreenMaskSize		db	0;
	GreenFieldPosition	db	0;
	BlueMaskSize		db	0;
	BlueFieldPosition	db	0;
	ReservedMaskSize	db	0;
	ReservedFieldPosition	db	0;
	DirectColourModeInfo	db	0;
	; // VBE 2.0 Extentions
	PhysBasePtr		dd	0;        // adresse phys du ptr LFB !
	OffScreenMemOffset	dd	0;
	OffScreenMemSize	dw  0
 
;Bourrage de 0 pour arriver a 510 octets
times 510-($-$$) db 0
 
;On ajoute le mot 0x55AA a l'envers car intel = Little Endian
dw 0xAA55
Si vous trouvez diverses erreurs dans le bootloader, merci de me le signaler, autant niveau commentaire que codage ^^.

Merci de votre aide, je vais continuer de chercher(mais je doute après 2h30 de recherche) des informations sur le mode vesa en mode texte(0x 108).

Sur ce bonne soirée
qnop est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/02/2012, 20h50   #2
Membre expérimenté
 
Avatar de edfed
 
être humain
Inscription : décembre 2007
Messages : 465
Détails du profil
Informations professionnelles :
Activité : être humain

Informations forums :
Inscription : décembre 2007
Messages : 465
Points : 582
Points : 582
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
mov eax, cr0
	and eax, 0xFE
	mov cr0, eax
 
	sti
 
	call switch
 
	cli	
	mov eax, cr0
	or	eax, 1
	mov cr0, eax
 
	mov byte [0xb8000], 'B'
	mov byte [0xb8001], 0b00001111
ici, le passage au mode reel necessite au moins le rechargement des registres CS et SS avec des descripteurs pour le mode reel avant le switch.
de plus, il faudrait encadrer tout le passage au mode reel par un cli/sti, meme les lignes sur le registre cr0. car si jamais tu as une interruption ou autre exception, ça risque de planter.

celà dit, tu peux aussi recuperer la fonte du bios, mais bon, elle est moche, puis ecrire une fonte n'est pas si dur, d'ailleur, changer de mode pour afficher du texte est un peu bancal, carr soit tu afficheras du texte, soit du graphisme, mais tu ne peut pas melanger l'utilisation de deux modes vga. ça serait un peu comme dire à une voiture d'utiliser la première et la marche arrière en meme temps, les modes graphiques, c'est l'un ou l'autre.
__________________
http://www.pending.me.uk/nmc/bla_1356091200.png
Vivement 21/12/2012
edfed est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/02/2012, 21h11   #3
Candidat au titre de Membre du Club
 
Inscription : mars 2006
Messages : 100
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 100
Points : 12
Points : 12
En fait je veux juste m'entrainer pour "switcher" entre le mode réel et le mode protéger même si j'en ai pas vraiment l'utilité en ce moment, ça pourrait venir pour la gestion du temps, car idem, je ne vois pas trop comment faire(vive le jeu du Snake haha) mais ce n'est pas encore trop urgent ^^.

Le fait de passer par des interruptions me rassurent un peu j'ai envie de dire. Tu parles de recharger au moins CS et SS, pour SS je vois comment faire. Par exemple

Code :
1
2
3
mov ax, 0x8000
mov ss, ax
mov esp, 0xf000
Mais pour CS?
Il faut faire un jmp?

Dans mon cas ce serait plus :
ou plutôt
Pour les fontes, je ne vois pas trop comment faire, mais je vais essayer de me renseigner, pour le chargement aussi ^^.
Rien que pour ouvrir un fichier déja, je pense pas savoir faire ^^, a moins de pouvoir utiliser des fonctions tels open?

Merci de ta patience^^.
qnop est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/02/2012, 01h06   #4
Membre expérimenté
 
Avatar de edfed
 
être humain
Inscription : décembre 2007
Messages : 465
Détails du profil
Informations professionnelles :
Activité : être humain

Informations forums :
Inscription : décembre 2007
Messages : 465
Points : 582
Points : 582
pour ss, il faut d'abord creer les descripteurs mode reel (un pour les datas, un pour le code)
ss utilise le segment de datas)
pour passer en mode protégé, il faut switcher, charger cs avec le jmp seg:next
, puis les autres segments avec leurs descripteurs egalement.
pour retourner au mode reel, il faut d'abord charger les autres segments avec un Descripteur Decrivant un segment de 64ko, dans la partie basse de la memoire, switcher en mode reel, empiler l'adresse mode reel puis charger le segment de code et ip avec retf.

si tu veux, j'ai un code tout fait qui date un peu. il y a une partie qui joue au switch pour les modes vesa justement, cette partie vient de dex4u, un anglais qui à codé un dos du meme nom.
voilà l'archive, à tester sous bochs, qemu, depuis une disquette, un disque dur, ou autre.

après, il faut bien avoir en tete que le vesa, ça rame enormement, il vaut mieu n'utiliser que des petites resolutions en attendant d'avoir un pilote pour la cg.

sous emulateur, ça rame reelement beaucoup, mais bon, ça suffit pour tester du code et des algos.
__________________
http://www.pending.me.uk/nmc/bla_1356091200.png
Vivement 21/12/2012
edfed est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/02/2012, 12h23   #5
Candidat au titre de Membre du Club
 
Inscription : mars 2006
Messages : 100
Détails du profil
Informations forums :
Inscription : mars 2006
Messages : 100
Points : 12
Points : 12
Salut.

D'après ce que j'ai vu, le vesa rame beaucoup moins que la SDL par exemple, donc personellement, ça me va :p ^^.

Ensuite pour le reste, c'est légèrement trop complexe pour moi, je pense booter directement depuis GRUB, car j'ai du mal a comprendre le chargement de plus de 255 secteurs. Je suis encore débutant en programmation, et je boot depuis une clef usb.

Puis je pense que je vais utiliser "LA MAGNIFIQUE" police du bios en 0xF000:0000 ^^.

Bref, merci quand même ^^ et bonne journée.
qnop est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 17h44.


 
 
 
 
Partenaires

Hébergement Web