My Project
Chargement...
Recherche...
Aucune correspondance
segment.c
Aller à la documentation de ce fichier.
1/*----------------------------------------------------------------------------*/
2/* Implantation des opérations de gestion des segments. */
3/* */
4/* (C) Manu Chaput 2000 */
5/*----------------------------------------------------------------------------*/
6#include <manux/errno.h> // ENOMEM
7#include <manux/debug.h> // paniqueNoyau
8#include <manux/i386.h>
9#include <manux/segment.h>
10#include <manux/printk.h>
11
13
14 struct __attribute__((__packed__)) {
15 uint16_t taille;
16 uint32_t adresse;
18
20 uint32_t adresse, uint32_t limite,
21 uint8_t type,
22 uint8_t gd0a)
23/*
24 * gd0a doit contenir dans son quadret de poids fort les bits G, D/B, 0
25 * et AVL ([1] p 3-11)
26 */
27{
28 if (dt->taille >= dt->capacite) {
29 return -ENOMEM;
30 }
31 dt->descripteur[dt->taille].ds.limiteFaible = (uint16_t)((limite)&0xFFFF);
32 dt->descripteur[dt->taille].ds.baseFaible = (uint16_t)((adresse)&0xFFFF);
33 dt->descripteur[dt->taille].ds.baseInter = (uint8_t)((adresse>>16)&0xFF);
34 dt->descripteur[dt->taille].ds.type = type;
35 dt->descripteur[dt->taille].ds.limiteFort = (uint8_t)((limite>>16)&0x0F)|gd0a;
36 dt->descripteur[dt->taille].ds.baseFort = (uint8_t)((adresse>>24)&0xFF);
37
38 return (dt->taille++)<<3;
39}
40
41static
42int setDescripteurTSS(DescriptorTable * dt,
43 uint32_t adresse, uint32_t limite,
44 uint8_t type,
45 uint8_t g00a)
46/*
47 * g00a doit contenir dans son quadret de poids fort les bits G, 0, 0
48 * et AVL ([1] p 6-7)
49 */
50{
51 if (dt->taille >= dt->capacite) {
52 return -1;
53 }
54 dt->descripteur[dt->taille].dt.limiteFaible = (uint16_t)((limite)&0xFFFF);
55 dt->descripteur[dt->taille].dt.baseFaible = (uint16_t)((adresse)&0xFFFF);
56 dt->descripteur[dt->taille].dt.baseInter = (uint8_t)((adresse>>16)&0xFF);
57 dt->descripteur[dt->taille].dt.type = type;
58 dt->descripteur[dt->taille].dt.limiteFort = (uint8_t)((limite>>16)&0x0F)|g00a;
59 dt->descripteur[dt->taille].dt.baseFort = (uint8_t)((adresse>>24)&0xFF);
60
61 return (dt->taille++)<<3;
62}
63
64inline
66/*
67 * Chargement effectif de la GDT ; lgdt prend en paramètre l'adresse
68 * d'une zone contenant la taille puis l'adresse de la GDT.
69 * On va mettre en place ici un modèle "flat" (deux segments qui
70 * couvrent 4G)
71 */
72{
73#define USE_LEGACY_NO
74
75#ifdef USE_LEGACY
76 uint16_t limite = 8*gdt->taille - 1;
77#else
78 descripteurGDT.taille = 8*gdt->taille - 1;
79 descripteurGDT.adresse = (uint32_t)&gdt->descripteur[0];
80#endif
81
82#ifdef USE_LEGACY
83 /* volatile uint8_t argument[6];
84
85 argument[0] = (limite) & 0xFF;
86 argument[1] = (limite>>8) & 0xFF;
87 argument[2] = ((uint32_t)(&gdt->descripteur[0]) & 0xFF);
88 argument[3] = (((uint32_t)(&gdt->descripteur[0])>>8) & 0xFF);
89 argument[4] = (((uint32_t)(&gdt->descripteur[0])>>16) & 0xFF);
90 argument[5] = (((uint32_t)(&gdt->descripteur[0])>>24) & 0xFF);
91 */
92 _chargerGDT((uint32_t)(&gdt->descripteur[0]), limite);
93
94#else
95 /*
96 asm volatile (
97 "movl %0, %%eax \n\t"
98 "lgdt (%%eax) \n\t"
99 "movl %%cr0, %%eax \n\t"
100 "or $1, %%eax \n\t"
101 "movl %%eax, %%cr0 \n\t"
102 "movw $0x08, %%ax \n\t"
103 "movw %%ax, %%cs \n\t"
104 "movw $0x10, %%ax \n\t"
105 "movw %%ax, %%ds \n\t"
106 "movw %%ax, %%es \n\t"
107 "movw %%ax, %%fs \n\t"
108 "movw %%ax, %%gs \n\t"
109 "movw $0x18, %%ax \n\t"
110 "movw %%ax, %%ss \n\t"
111 "ljmp $0x08,$vidageCache \n\t"
112 "vidageCache : \n\t"
113 ::"r"((uint32_t)&descripteurGDT):"eax"
114 );
115
116 */
117 asm volatile (
118 "movl %0, %%eax \n\t"
119 "lgdt (%%eax) \n\t"
120 "ljmp $0x08,$vidageDuCache_%= \n\t"
121 "vidageDuCache_%= : \n\t"
122 "movw $0x10, %%ax \n\t"
123 "movw %%ax, %%ds \n\t"
124 "movw %%ax, %%es \n\t"
125 "movw %%ax, %%fs \n\t"
126 "movw %%ax, %%gs \n\t"
127 "movw $0x18, %%ax \n\t"
128 "movw %%ax, %%ss \n\t"
129 "movl %%cr0, %%eax \n\t"
130 "or $1, %%eax \n\t"
131 "movl %%eax, %%cr0 \n\t"
132 ::"r"((uint32_t)&descripteurGDT):"eax"
133 );
134#endif
135}
136
138/*
139 * Chargement effectif de la LDT ; lldt prend en paramètre l'adresse
140 * d'une zone contenant la taille puis l'adresse de la LDT.
141 */
142{
143 uint16_t limite = 8*ldt->taille - 1;
144 volatile uint8_t argument[6];
145
146 argument[0] = (limite) & 0xFF;
147 argument[1] = (limite>>8) & 0xFF;
148 argument[2] = ((uint32_t)(&ldt->descripteur[0]) & 0xFF);
149 argument[3] = (((uint32_t)(&ldt->descripteur[0])>>8) & 0xFF);
150 argument[4] = (((uint32_t)(&ldt->descripteur[0])>>16) & 0xFF);
151 argument[5] = (((uint32_t)(&ldt->descripteur[0])>>24) & 0xFF);
152
153 __asm__ __volatile__ ("lldt (%0)": :"a" ((char *)argument));// + sti ?
154}
155
157{
158 int resultat;
159#define MANUX_GDT_CS 0x08
160#define MANUX_GDT_DS 0x10
161#define MANUX_GDT_SS 0x18
162
164
166 gdtSysteme->taille = 0;
167
168 /* Le segment nul (obligatoire) */
169 resultat = setDescripteurSegment(gdtSysteme, 0, 0, 0, 0);
170 if (resultat != 0x00) {
171 paniqueNoyau("Probleme sur le segment nul en %d\n", resultat);
172 }
173
174 // WARNING pour quoi si je change l'ordre de création (et donc bien
175 // sur le numéro de façon cohérente) cela ne fonctionne pas !?
176 //
177 // Le segment de code qui commmence à l'adresse 0, avec une limite
178 // à 1 méga(pages puisque Gr=1), donc 4G de mémoire.
179 // g00a = 1100 (Gr=1 : blocs de 4K, Sz=1 32 bits protected)
180 // type = 10011010
181 // present, priv=0, code/data, exec, dir up, read, access = 0
182 resultat = setDescripteurSegment(gdtSysteme, 0, 0xFFFFFFFF, 0x9A, 0xC0);
183 if (resultat != MANUX_GDT_CS) {
184 paniqueNoyau("Probleme sur le segment de code en %d\n", resultat);
185 }
186
187 // Le segment de data qui commmence à l'adresse 0, avec une limite
188 // à 1 méga(pages puisque Gr=1), donc 4G de mémoire.
189 // g00a = 1100 (Gr=1 : blocs de 4K, Sz=1 32 bits protected)
190 // type = 10010010
191 // present, priv=0, code/data, noexec, dir up, rw, access = 0
192 resultat = setDescripteurSegment(gdtSysteme, 0, 0xFFFFFFFF, 0x92, 0xC0);
193 if (resultat != MANUX_GDT_DS) {
194 paniqueNoyau("Probleme sur le segment de donnees en %d\n", resultat);
195 }
196
197 // Le segment de pile qui commmence à l'adresse 0, avec une limite
198 // à 1 méga(pages puisque Gr=1), donc 4G de mémoire.
199 // g00a = 1100 (Gr=1 : blocs de 4K, Sz=1 32 bits protected)
200 // type = 10010010
201 // present, priv=0, code/data, noexec, dir up, rw, access = 0
202 resultat = setDescripteurSegment(gdtSysteme, 0, 0xFFFFFFFF, 0x92, 0xC0);
203 if (resultat != MANUX_GDT_SS) {
204 paniqueNoyau("Probleme sur le segment de pile en %d\n", resultat);
205 }
206
207 /* On charge la GDT */
209}
210
212 void * adresse, uint32_t limite,
213 booleen busyTask)
214{
215 int resultat;
216
217 if (busyTask) {
218 resultat = setDescripteurTSS(dt, (uint32_t)adresse, limite, 0x8B, 0x90);
219 } else {
220 resultat = setDescripteurTSS(dt, (uint32_t)adresse, limite, 0x89, 0x90);
221 }
222
223 return resultat;
224}
225
226[[maybe_unused]]
227static
228void busifier(uint16_t offsetTSS)
229{
230 gdtSysteme->descripteur[offsetTSS>>3].dt.type |= 0x02;
231}
232
233[[maybe_unused]]
234static
235void debusifier(uint16_t offsetTSS)
236{
237 gdtSysteme->descripteur[offsetTSS>>3].dt.type &= 0xFD;
238}
#define MANUX_TAILLE_PAGE
#define ENOMEM
Definition errno.h:13
void _chargerGDT(uint32_t ad, uint16_t limite)
Définition des fonctions de base d'entrée-sortie du noyau.
unsigned long uint32_t
Definition types.h:20
unsigned short uint16_t
Definition types.h:16
int booleen
Definition types.h:32
unsigned char uint8_t
Definition types.h:12
#define paniqueNoyau(fmt, args...)
Definition debug.h:107
#define MANUX_GDT_NB_PAGES
#define MANUX_ADRESSE_GDT
#define MANUX_GDT_DS
descripteurGDT
Definition segment.c:17
#define MANUX_GDT_CS
void chargerLDT(DescriptorTable *ldt)
Definition segment.c:137
int setDescripteurSegment(DescriptorTable *dt, uint32_t adresse, uint32_t limite, uint8_t type, uint8_t gd0a)
Definition segment.c:19
int ajouterDescTSS(DescriptorTable *dt, void *adresse, uint32_t limite, booleen busyTask)
Definition segment.c:211
void chargerGDT(DescriptorTable *gdt)
Definition segment.c:65
DescriptorTable * gdtSysteme
Definition segment.c:12
struct __attribute__((__packed__))
Definition segment.c:14
#define MANUX_GDT_SS
void initialiserGDT(void)
Definition segment.c:156
union _Descripteur Descripteur
uint16_t baseFaible
Definition segment.h:16
uint8_t limiteFort
Definition segment.h:19
uint8_t baseInter
Definition segment.h:17
uint16_t limiteFaible
Definition segment.h:15
uint8_t type
Definition segment.h:18
uint8_t baseFort
Definition segment.h:20
uint8_t type
Definition segment.h:30
uint16_t baseFaible
Definition segment.h:28
uint16_t limiteFaible
Definition segment.h:27
uint8_t baseInter
Definition segment.h:29
uint8_t limiteFort
Definition segment.h:31
uint8_t baseFort
Definition segment.h:32
Descripteur descripteur[0]
Definition segment.h:47
DescSegment ds
Definition segment.h:36
DescTSS dt
Definition segment.h:37