Diff markup
001 001
002 /* 002 /*
003 * @(#) $Id: bootsect.S,v 1.5 2004/03/25 09:53 !! 003 * @(#) $Id: bootsect.S,v 1.6 2004/06/18 07:43:51 d2 Exp $
004 * Description : Bootsecteur en syntaxe AT&T 004 * Description : Bootsecteur en syntaxe AT&T
005 * Auteurs : Thomas Petazzoni & Fabrice Gautie 005 * Auteurs : Thomas Petazzoni & Fabrice Gautier & Emmanuel Marty
006 * Jerome Petazzoni & Bernard Cassag 006 * Jerome Petazzoni & Bernard Cassagne & coffeeman
007 * David Decotigny 007 * David Decotigny
008 * Bug reports to kos-misc@enix.org 008 * Bug reports to kos-misc@enix.org
009 */ 009 */
010 010
011 /* 011 /*
012 * But global de ce bootsecteur : 012 * But global de ce bootsecteur :
013 * 013 *
014 * - Initialiser la becane 014 * - Initialiser la becane
015 * - Charger le kernel 015 * - Charger le kernel
016 * - Passer en mode protege 016 * - Passer en mode protege
017 * - Executer le kernel 017 * - Executer le kernel
018 * 018 *
019 * Taille restante : Je vous rappelle qu'un bo 019 * Taille restante : Je vous rappelle qu'un bootsecteur ne peut faire
020 * qu'au maximum 512 octets dont 2 octets obli 020 * qu'au maximum 512 octets dont 2 octets obligatoires 0xAA55. Sur
021 * les 510 octets reellement utilisables, il r 021 * les 510 octets reellement utilisables, il reste 3 octets dispo (60
022 * si on decide d'enlever le BPB un jour) !!! 022 * si on decide d'enlever le BPB un jour) !!!
023 * 023 *
024 * thomas_petazzoni : - detection des codes d 024 * thomas_petazzoni : - detection des codes d'erreurs de chargement
025 * David_Decotigny : - Passage en GNU as 025 * David_Decotigny : - Passage en GNU as
026 * David_Decotigny : - Chargement du noyau a 026 * David_Decotigny : - Chargement du noyau au-dela du 1er Mega (taille
027 * max = 0x9e000 octets 027 * max = 0x9e000 octets = 632ko), pour avoir le
028 * meme noyau sous grub 028 * meme noyau sous grub et avec le bootsecteur
029 */ 029 */
030 030
031 /* 031 /*
032 * Sequence d'operations : 032 * Sequence d'operations :
033 * - Le BIOS charge le bootsect en 0x7c00 (BO 033 * - Le BIOS charge le bootsect en 0x7c00 (BOOT_ADRESS). On choisit
034 * la representation 0x7c0:0000 pour que le 034 * la representation 0x7c0:0000 pour que le .org 0 reste valide
035 * - Le bootsect se deplace de lui-meme en 0x 035 * - Le bootsect se deplace de lui-meme en 0x9f000 (COPY_ADRESS). On
036 * choisit la representation 0x9f00:0000 po 036 * choisit la representation 0x9f00:0000 pour que le .org 0 reste
037 * valide 037 * valide
038 * - Le bootsect verifie que le processeur es 038 * - Le bootsect verifie que le processeur est du type 386+
039 * - Il charge le noyau depuis la disquette e 039 * - Il charge le noyau depuis la disquette en memoire a partir de
040 * 0x1000 (LOAD_ADRESS). Le noyau peut au m 040 * 0x1000 (LOAD_ADRESS). Le noyau peut au max tenir sur
041 * SECTORS_TO_LOAD secteurs 041 * SECTORS_TO_LOAD secteurs
042 * - Il passe en pmode flat (apres ouverture 042 * - Il passe en pmode flat (apres ouverture a20)
043 * - Il recopie le noyau (situe en LOAD_ADRES 043 * - Il recopie le noyau (situe en LOAD_ADRESS) vers son adresse
044 * finale (FINAL_ADDRESS = 2Mo). La recopie 044 * finale (FINAL_ADDRESS = 2Mo). La recopie se fait sur tout l'espace
045 * LOAD_ADRESS ---> COPY_ADRESS, c'est a di 045 * LOAD_ADRESS ---> COPY_ADRESS, c'est a dire sur 0x9e000 octets =
046 * 632ko. Le noyau peut donc au max faire 6 046 * 632ko. Le noyau peut donc au max faire 632ko. Le nombre max de
047 * secteurs de disquette qu'on peut charger 047 * secteurs de disquette qu'on peut charger est donc 1264
048 */ 048 */
049 049
050 050
051 /* La taille de la pile */ 051 /* La taille de la pile */
052 #define BOOT_STACK_SIZE 0x4000 052 #define BOOT_STACK_SIZE 0x4000
053 053
054 .file "bootsect.S" 054 .file "bootsect.S"
055 055
056 /* Tout est place dans une seule secti 056 /* Tout est place dans une seule section */
057 .section ".bootsect" 057 .section ".bootsect"
058 058
059 /* L'essentiel du bootsector (sauf les 059 /* L'essentiel du bootsector (sauf les 1eres instructions)
060 sont a un offset 0. On fait en sort 060 sont a un offset 0. On fait en sorte que le compilo soit
061 d'accord la-dessus. Quand on a des 061 d'accord la-dessus. Quand on a des adresse realm exotiques
062 (0x7c00, 0x9f000, ...), on s'arrang 062 (0x7c00, 0x9f000, ...), on s'arrange toujours pour avoir un
063 offset de 0 => on choisira le segme 063 offset de 0 => on choisira le segment adapte (0x7c0,
064 0x9f00, ...). Il ne faut pas oublie 064 0x9f00, ...). Il ne faut pas oublier le ld -Ttext 0 */
065 .org 0 065 .org 0
066 066
067 /* Pour que gas genere du 16bits, afin 067 /* Pour que gas genere du 16bits, afin que ca marche en realm */
068 .code16 068 .code16
069 069
070 #define SECTORS_TO_LOAD 128 /* 64 ko */ /* MAX 070 #define SECTORS_TO_LOAD 128 /* 64 ko */ /* MAX=1264 */
071 071
072 /* 072 /*
073 * Parametres de la disquette. Comme c'est chi 073 * Parametres de la disquette. Comme c'est chiant de faire une
074 * procedure de detection auto, et que ca pren 074 * procedure de detection auto, et que ca prend de la place, on fait
075 * ca "a la main". Par exemple, une DD 720 Ko 075 * ca "a la main". Par exemple, une DD 720 Ko a 9 secteurs/piste, une
076 * 1.44 Mo a 18 secteurs/pistes 076 * 1.44 Mo a 18 secteurs/pistes
077 */ 077 */
078 #define CYLS 80 078 #define CYLS 80
079 #define HEADS 1 079 #define HEADS 1
080 #define SECTS 18 080 #define SECTS 18
081 081
082 #define BOOT_ADRESS 0x07C00 /* Adre 082 #define BOOT_ADRESS 0x07C00 /* Adresse de demarrage (lineaire) */
083 #define BOOT_SEG (BOOT_ADRESS>>4) /* Segm 083 #define BOOT_SEG (BOOT_ADRESS>>4) /* Segment de Boot */
084 #define BOOT_SIZE 512 /* Tail 084 #define BOOT_SIZE 512 /* Taille bu bootsecteur */
085 #define COPY_ADRESS 0x9F000 /* La o 085 #define COPY_ADRESS 0x9F000 /* La ou on va copier le
086 boot 086 bootsecteur (lineaire) */
087 #define COPY_SEG (COPY_ADRESS>>4) /* Segm 087 #define COPY_SEG (COPY_ADRESS>>4) /* Segment de la ou on va
088 copi 088 copier le bootsecteur */
089 #define LOAD_ADRESS 0x01000 /* 1er 089 #define LOAD_ADRESS 0x01000 /* 1er chargement du systeme */
090 #define LOAD_SEG (LOAD_ADRESS>>4) /* Segm 090 #define LOAD_SEG (LOAD_ADRESS>>4) /* Segment du 1er chargement du */
091 #define MAX_KERN_LEN COPY_ADRESS-LOAD_ADRESS / 091 #define MAX_KERN_LEN COPY_ADRESS-LOAD_ADRESS /* Taille noyau maxi */
092 092
093 /* IMPORTANT : Cette valeur DOIT etre identiqu 093 /* IMPORTANT : Cette valeur DOIT etre identique a l'adresse presente
094 dans kos.lds ! */ !! 094 dans sos.lds ! */
095 #define FINAL_ADDRESS 0x200000 /* Adre 095 #define FINAL_ADDRESS 0x200000 /* Adresse finale (physique de 0 a 4G)
096 ou e 096 ou est charge le noyau */
097 097
098 #define OP16 .byte 0x66 ; 098 #define OP16 .byte 0x66 ;
099 #define OP32 .byte 0x66 ; 099 #define OP32 .byte 0x66 ;
100 100
101 /* 101 /*
102 * Procedure qui vide le buffer clavier. 102 * Procedure qui vide le buffer clavier.
103 */ 103 */
104 #define WAITKB \ 104 #define WAITKB \
105 1: ;\ 105 1: ;\
106 .word 0xeb ;\ 106 .word 0xeb ;\
107 .word 0xeb ;\ 107 .word 0xeb ;\
108 inb $0x64, %al ;\ 108 inb $0x64, %al ;\
109 andb $0x2, %al ;\ 109 andb $0x2, %al ;\
110 jnz 1b 110 jnz 1b
111 111
112 /* Le point d'entree dans le bootsect 112 /* Le point d'entree dans le bootsect */
113 .globl _bsect 113 .globl _bsect
114 _bsect: 114 _bsect:
115 115
116 /* 116 /*
117 * La portion qui suit est situee a un 117 * La portion qui suit est situee a un offset 0x7c00 en
118 * memoire. Attention donc aux referen 118 * memoire. Attention donc aux references memoire dans cette
119 * partie. On choisit de rester en off 119 * partie. On choisit de rester en offset 0 (.org 0), mais on
120 * charge correctement les segments a 120 * charge correctement les segments a 0x7c0.
121 */ 121 */
122 122
123 movw $BOOT_SEG, %ax /* le bootsecteur 123 movw $BOOT_SEG, %ax /* le bootsecteur est a 0x7C00 en lineaire */
124 movw %ax, %ds /* on le copie a l' 124 movw %ax, %ds /* on le copie a l'adresse COPY_ADRESS */
125 xorw %si, %si /* comme cette adre 125 xorw %si, %si /* comme cette adresse est la plus haute de la mem */
126 xorw %di, %di /* on pourra charge 126 xorw %di, %di /* on pourra charger un kernel + gros */
127 movw $(BOOT_SIZE>>1), %cx 127 movw $(BOOT_SIZE>>1), %cx
128 movw $COPY_SEG, %ax 128 movw $COPY_SEG, %ax
129 movw %ax, %es 129 movw %ax, %es
130 cld 130 cld
131 rep ; movsw 131 rep ; movsw
132 132
133 /* on continue a executer le bootsecte 133 /* on continue a executer le bootsecteur, mais maintenant a
134 partir de 0x9F000, qu'on represente 134 partir de 0x9F000, qu'on represente sous la forme
135 0x9f00:offset */ 135 0x9f00:offset */
136 ljmp $COPY_SEG, $here 136 ljmp $COPY_SEG, $here
137 137
138 /* 138 /*
139 * A partir de maintenant, on est a un 139 * A partir de maintenant, on est a un offset 0 en memoire
140 * (segment 0x9f00), conformement a ce 140 * (segment 0x9f00), conformement a ce que veut le compilo.
141 */ 141 */
142 here: 142 here:
143 movw %ax, %ds 143 movw %ax, %ds
144 144
145 /* Petite pile temporaire (1k - 3.84k 145 /* Petite pile temporaire (1k - 3.84k en RAM ; les adresses 0-1k
146 correspondent au vecteur d'interrup 146 correspondent au vecteur d'interruptions). */
147 movw %ax, %ss 147 movw %ax, %ss
148 movw $(LOAD_ADRESS - 0x10), %sp 148 movw $(LOAD_ADRESS - 0x10), %sp
149 149
150 /* Efface l'ecran */ 150 /* Efface l'ecran */
151 movb $0x0, %ah 151 movb $0x0, %ah
152 movb $0x3, %al 152 movb $0x3, %al
153 int $0x10 153 int $0x10
154 154
155 /* Affiche les messages d'attente */ 155 /* Affiche les messages d'attente */
156 movw $loadkern, %si 156 movw $loadkern, %si
157 call message 157 call message
158 movw $check, %si 158 movw $check, %si
159 call message 159 call message
160 160
161 check386: 161 check386:
162 /* 162 /*
163 * la attention, plus complexe : on te 163 * la attention, plus complexe : on teste si le proc est un
164 * 386+ pour cela, on va essayer de mo 164 * 386+ pour cela, on va essayer de modifier les bits 12 ? 14
165 * du registre E-flag si la modificati 165 * du registre E-flag si la modification reste, alors le proc
166 * est un 386+, sinon, c'est =< 286 166 * est un 386+, sinon, c'est =< 286
167 * 167 *
168 * Merci a Emmanuel Marty pour la comp 168 * Merci a Emmanuel Marty pour la compatibilite avec les 386
169 * "pre-jurassique" 169 * "pre-jurassique"
170 */ 170 */
171 171
172 pushf /* on sauvegarde le E-Flag */ 172 pushf /* on sauvegarde le E-Flag */
173 movb $0x70, %ah 173 movb $0x70, %ah
174 pushw %ax 174 pushw %ax
175 popf 175 popf
176 pushf 176 pushf
177 popw %ax 177 popw %ax
178 orb %ah, %ah 178 orb %ah, %ah
179 je no386 /* si la modif n'est pas val 179 je no386 /* si la modif n'est pas valable, alors on saute a
180 no386 */ 180 no386 */
181 popf /* on les restaure ? la fin 181 popf /* on les restaure ? la fin ... */
182 182
183 /* Message de confirmation de 386+ et 183 /* Message de confirmation de 386+ et d'attente */
184 movw $found386, %si 184 movw $found386, %si
185 call message 185 call message
186 movw $loading, %si 186 movw $loading, %si
187 call message 187 call message
188 188
189 /* Copie du noyau disquette => RAM a partir de 189 /* Copie du noyau disquette => RAM a partir de 0x1000
190 L'adresse de destination est définie par es 190 L'adresse de destination est définie par es:0, où es vaut
191 initialement 0x100 (ie correspond alors à l 191 initialement 0x100 (ie correspond alors à l'adresse 256*16, soit 4
192 ko). Chaque itération incrémente ce registr 192 ko). Chaque itération incrémente ce registre es de 32, ce qui
193 correspond à un bond de 32*16 en mémoire, s 193 correspond à un bond de 32*16 en mémoire, soit la taille d'un
194 secteur. De cette façon, puisqu'on joue sur 194 secteur. De cette façon, puisqu'on joue sur les segments plutôt que
195 sur les offsets, la taille du noyau n'est p 195 sur les offsets, la taille du noyau n'est pas limitée à 64 ko. Elle
196 est limitée par contre à la taille de la mé 196 est limitée par contre à la taille de la mémoire disponible sous
197 les 1Mo, \ie 640 ko (0x9f000 - 0x1000). */ 197 les 1Mo, \ie 640 ko (0x9f000 - 0x1000). */
198 copyKernel: 198 copyKernel:
199 /* Chargement du noyau en LOAD_SEG:0 * 199 /* Chargement du noyau en LOAD_SEG:0 */
200 /* 3 iterateurs : 200 /* 3 iterateurs :
201 - load_size : le nbre de secte 201 - load_size : le nbre de secteurs a charger
202 - cl : le secteur ou on en est 202 - cl : le secteur ou on en est pour le
203 cylindre en cours (<= SECTS) 203 cylindre en cours (<= SECTS)
204 - dh : la tete en cours (0/1) 204 - dh : la tete en cours (0/1)
205 */ 205 */
206 movb $0, %dl 206 movb $0, %dl
207 movw $LOAD_SEG, %ax 207 movw $LOAD_SEG, %ax
208 movw %ax, %es 208 movw %ax, %es
209 209
210 xorw %bx, %bx 210 xorw %bx, %bx
211 xorw %dx, %dx 211 xorw %dx, %dx
212 movw $1, %cx /* premier secteur * 212 movw $1, %cx /* premier secteur */
213 213
214 .nextsector: /* prochain secteur * 214 .nextsector: /* prochain secteur */
215 incb %cl /* en incrementant CL 215 incb %cl /* en incrementant CL */
216 cmpb $SECTS, %cl /* si CL =< SECTS (=n 216 cmpb $SECTS, %cl /* si CL =< SECTS (=nbre de secteurs/pistes)
217 alors on charge */ 217 alors on charge */
218 jbe .sector 218 jbe .sector
219 movb $1, %cl /* sinon on revient a 219 movb $1, %cl /* sinon on revient au secteur 1 */
220 incb %dh /* mais sur l'autre t 220 incb %dh /* mais sur l'autre tete */
221 cmpb $1, %dh /* on recompare, si D 221 cmpb $1, %dh /* on recompare, si DH =< 1 */
222 je .sector /* on charge */ 222 je .sector /* on charge */
223 movb $0, %dh /* sinon on repasse a 223 movb $0, %dh /* sinon on repasse a la tete 0 */
224 incb %ch /* mais on change de 224 incb %ch /* mais on change de cylindre */
225 225
226 .sector: 226 .sector:
227 pushw %es 227 pushw %es
228 movw $0x0201, %ax /* service 0x2, char 228 movw $0x0201, %ax /* service 0x2, chargement 0x1 seecteur */
229 int $0x13 /* Go ! */ 229 int $0x13 /* Go ! */
230 jc halt /* erreur */ 230 jc halt /* erreur */
231 popw %ax 231 popw %ax
232 addw $32, %ax /* on a charge un se 232 addw $32, %ax /* on a charge un secteur, donc on doit
233 charger 512 bytes 233 charger 512 bytes plus loin */
234 movw %ax, %es /* on avance donc le 234 movw %ax, %es /* on avance donc le segment du buffer de
235 32bytes, ie 1 sec 235 32bytes, ie 1 secteur en RAM (car 32*16=512) */
236 236
237 movw $(0x0E*256+'.'), %ax /* affiche u 237 movw $(0x0E*256+'.'), %ax /* affiche un point */
238 int $0x10 238 int $0x10
239 239
240 decw (load_size) /* et on repart p 240 decw (load_size) /* et on repart pour le prochain secteur
241 tant qu'on n'a pa 241 tant qu'on n'a pas fini ! */
242 jnz .nextsector 242 jnz .nextsector
243 243
244 after: 244 after:
245 movw $0x03f2, %dx 245 movw $0x03f2, %dx
246 inb %dx, %al /* stoppe le moteur */ 246 inb %dx, %al /* stoppe le moteur */
247 andb $0x0f, %al 247 andb $0x0f, %al
248 outb %al, %dx 248 outb %al, %dx
249 249
250 cli /* on interdit les i 250 cli /* on interdit les interruptions */
251 251
252 fincopie: 252 fincopie:
253 pushw %cs 253 pushw %cs
254 popw %ds 254 popw %ds
255 255
256 /* on ouvre la porte A20 */ 256 /* on ouvre la porte A20 */
257 WAITKB /* on vide le buffer 257 WAITKB /* on vide le buffer */
258 movb $0xd1, %al /* on met a jour le po 258 movb $0xd1, %al /* on met a jour le port */
259 outb %al, $0x64 259 outb %al, $0x64
260 WAITKB 260 WAITKB
261 movb $0xdf, %al /* bit 2 = ouverture/f 261 movb $0xdf, %al /* bit 2 = ouverture/fermeture */
262 outb %al, $0x60 262 outb %al, $0x60
263 263
264 /* 264 /*
265 * init gdt 265 * init gdt
266 */ 266 */
267 InitGDT: 267 InitGDT:
268 /* Préparation du flat mode */ 268 /* Préparation du flat mode */
269 lgdt gdtr 269 lgdt gdtr
270 270
271 GoPMode: 271 GoPMode:
272 /* Passage en mode protégé */ 272 /* Passage en mode protégé */
273 movl %cr0, %eax 273 movl %cr0, %eax
274 orb $1, %al /* set PE bit to 1 */ 274 orb $1, %al /* set PE bit to 1 */
275 movl %eax, %cr0 275 movl %eax, %cr0
276 276
277 /* we are not yet in Pmode jump 'in' p 277 /* we are not yet in Pmode jump 'in' pmode clearing prefetch
278 * queue and loading a new selector */ 278 * queue and loading a new selector */
279 movw $0x10, %ax 279 movw $0x10, %ax
280 movw %ax, %ds 280 movw %ax, %ds
281 movw %ax, %es 281 movw %ax, %es
282 movw %ax, %fs 282 movw %ax, %fs
283 movw %ax, %gs 283 movw %ax, %gs
284 284
285 /* 285 /*
286 * Code 32 bits ============================== 286 * Code 32 bits ============================================================
287 */ 287 */
288 .code32 288 .code32
289 289
290 JumpToHere32: /* Se deplace a l'endroit actuel 290 JumpToHere32: /* Se deplace a l'endroit actuel, en passant en 32bits
291 et en utilisant la gdt, et vi 291 et en utilisant la gdt, et vide la prefetch queue */
292 .byte 0x66 /* Prefixe 32bits : en real 292 .byte 0x66 /* Prefixe 32bits : en realite, jusqu'au jmp, on est
293 encore en 16 bits */ 293 encore en 16 bits */
294 ljmp $0x8, $(COPY_ADRESS+(Here32)) 294 ljmp $0x8, $(COPY_ADRESS+(Here32))
295 Here32: 295 Here32:
296 /* Et voila : On est en 32 bits vrai * 296 /* Et voila : On est en 32 bits vrai */
297 297
298 MoveKernelToFinalAddr: /* Deplace le noyau (en 298 MoveKernelToFinalAddr: /* Deplace le noyau (en LOAD_ADDRESS) vers sa
299 destination finale ( 299 destination finale (FINAL_ADDRESS) */
300 movl $0x10, %eax 300 movl $0x10, %eax
301 movl %eax, %ds /* Seg Src = DSeg */ 301 movl %eax, %ds /* Seg Src = DSeg */
302 movl %eax, %es /* Sed Dest = DSeg */ 302 movl %eax, %es /* Sed Dest = DSeg */
303 cld 303 cld
304 movl $LOAD_ADRESS, %esi /* On comme 304 movl $LOAD_ADRESS, %esi /* On commence la copie au debut du noyau */
305 movl $FINAL_ADDRESS, %edi /* On copie 305 movl $FINAL_ADDRESS, %edi /* On copie vers cette adresse */
306 movl $MAX_KERN_LEN, %ecx /* Taille r 306 movl $MAX_KERN_LEN, %ecx /* Taille recopie */
307 shrl $2, %ecx 307 shrl $2, %ecx
308 rep 308 rep
309 movsl 309 movsl
310 310
311 LaunchKernel: 311 LaunchKernel:
312 /* Met en place une pile au niveau du 312 /* Met en place une pile au niveau du symbole "stack" */
313 movl %eax, %ss 313 movl %eax, %ss
314 movl $(stack + BOOT_STACK_SIZE), %ebp 314 movl $(stack + BOOT_STACK_SIZE), %ebp
315 movl %ebp, %esp 315 movl %ebp, %esp
316 316
317 /* Saut vers le noyau. La GDT est en p 317 /* Saut vers le noyau. La GDT est en place (flat mode), les
318 * selecteurs aussi, a20 est ouverte, 318 * selecteurs aussi, a20 est ouverte, et les interruptions sont
319 * cli + pas de idt. Le PIC n'est pas 319 * cli + pas de idt. Le PIC n'est pas programme */
320 ljmp $0x8, $sos_main 320 ljmp $0x8, $sos_main
321 321
322 /* 322 /*
323 * Utilities ================================= 323 * Utilities ============================================================
324 */ 324 */
325 .code16 325 .code16
326 326
327 message: 327 message:
328 lodsb /* charge ds:si dans 328 lodsb /* charge ds:si dans al et incremente si */
329 orb %al, %al /* si al = 0 */ 329 orb %al, %al /* si al = 0 */
330 jz 1f 330 jz 1f
331 movb $0x0e, %ah /* service 0Eh (affi 331 movb $0x0e, %ah /* service 0Eh (affichage d'un caractere) */
332 movw $0x0007, %bx /* Parametres : blan 332 movw $0x0007, %bx /* Parametres : blanc sur fond noir */
333 int $0x10 /* Appel de l'inter 333 int $0x10 /* Appel de l'interruption 10h */
334 jmp message /* On repart au débu 334 jmp message /* On repart au début ... */
335 1: ret /* si la chaine est 335 1: ret /* si la chaine est finie alors on retourne
336 dans la fonction 336 dans la fonction appelante */
337 337
338 halt: 338 halt:
339 pushw %cs 339 pushw %cs
340 popw %es 340 popw %es
341 movw $haltmsg, %si 341 movw $haltmsg, %si
342 call message 342 call message
343 cli 343 cli
344 1: jmp 1b 344 1: jmp 1b
345 ret 345 ret
346 346
347 no386: 347 no386:
348 movw $need386, %si 348 movw $need386, %si
349 call message 349 call message
350 call halt 350 call halt
351 351
352 /* 352 /*
353 * GDT 353 * GDT
354 */ 354 */
355 355
356 gdt: 356 gdt:
357 gdtr: 357 gdtr:
358 NULL_Desc: 358 NULL_Desc:
359 .word (EndGDT)-(gdt)-1 /* Taille GDT * 359 .word (EndGDT)-(gdt)-1 /* Taille GDT */
360 .long (gdt)+COPY_ADRESS 360 .long (gdt)+COPY_ADRESS
361 unused: 361 unused:
362 .word 0 362 .word 0
363 363
364 CS_Desc: /* 0x8 */ 364 CS_Desc: /* 0x8 */
365 .word 0xFFFF, 0 365 .word 0xFFFF, 0
366 .byte 0, 0x9B, 0xCF, 0 366 .byte 0, 0x9B, 0xCF, 0
367 367
368 DS_Desc: /* 0x10 */ 368 DS_Desc: /* 0x10 */
369 .word 0xFFFF, 0 369 .word 0xFFFF, 0
370 .byte 0, 0x93, 0xCF, 0 370 .byte 0, 0x93, 0xCF, 0
371 371
372 EndGDT: 372 EndGDT:
373 373
374 /* quelques messages */ 374 /* quelques messages */
375 375
376 loadkern: .string "-= S O S =- : The Sim 376 loadkern: .string "-= S O S =- : The Simple Operating System \r\n"
377 check: .string "Checking for a 386+ p 377 check: .string "Checking for a 386+ processor... "
378 found386: .string " [OK]\r\n" 378 found386: .string " [OK]\r\n"
379 need386: .string " [FAILED]\r\n" 379 need386: .string " [FAILED]\r\n"
380 diskerror: .string "Disk Error\r\n" 380 diskerror: .string "Disk Error\r\n"
381 loading: .string "Loading... " 381 loading: .string "Loading... "
382 haltmsg: .string "System Halted\r\n" 382 haltmsg: .string "System Halted\r\n"
383 383
384 /*** Les code/données du boot secteur se termi 384 /*** Les code/données du boot secteur se terminent ICI. le marqueur de
385 * fin (aa55) est ajouté automatiquement par l 385 * fin (aa55) est ajouté automatiquement par le script ld
386 * sos_bsect.lds ***/ 386 * sos_bsect.lds ***/
387 387
388 /* La pile de 16k qu'on utilise au niveau de L 388 /* La pile de 16k qu'on utilise au niveau de LaunchKernel se trouve
389 declaree avec le noyau, dans sa section ".b 389 declaree avec le noyau, dans sa section ".bss", cad HORS du boot
390 secteur ! (sinon ca depasserait 512B, forcé 390 secteur ! (sinon ca depasserait 512B, forcément). On aurait pu la
391 définir directement dans le sos_bsect.lds, 391 définir directement dans le sos_bsect.lds, ou dans un fichier .c
392 auxiliaire pour plus de clarté */ 392 auxiliaire pour plus de clarté */
393 .comm stack, BOOT_STACK_SIZE 393 .comm stack, BOOT_STACK_SIZE