Diff markup
001 001
002 /* 002 /*
003 * @(#) $Id: bootsect.S,v 1.12 2005/08/13 13:4 !! 003 * @(#) $Id: bootsect.S,v 1.5 2004/03/25 09:53:58 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 (SOS integration !! 007 * David Decotigny
008 * Christopher Goyet (RAM size deter <<
009 * Bug reports to kos-misc@enix.org 008 * Bug reports to kos-misc@enix.org
010 */ 009 */
011 010
012 /* 011 /*
013 * But global de ce bootsecteur : 012 * But global de ce bootsecteur :
014 * 013 *
015 * - Initialiser la becane 014 * - Initialiser la becane
016 * - Charger le kernel 015 * - Charger le kernel
017 * - Passer en mode protege 016 * - Passer en mode protege
018 * - Executer le kernel 017 * - Executer le kernel
019 * 018 *
020 * Taille restante : Je vous rappelle qu'un bo 019 * Taille restante : Je vous rappelle qu'un bootsecteur ne peut faire
021 * qu'au maximum 512 octets dont 2 octets obli 020 * qu'au maximum 512 octets dont 2 octets obligatoires 0xAA55. Sur
022 * les 510 octets reellement utilisables, il r 021 * les 510 octets reellement utilisables, il reste 3 octets dispo (60
023 * si on decide d'enlever le BPB un jour) !!! 022 * si on decide d'enlever le BPB un jour) !!!
024 * 023 *
025 * thomas_petazzoni : - detection des codes d 024 * thomas_petazzoni : - detection des codes d'erreurs de chargement
026 * David_Decotigny : - Passage en GNU as 025 * David_Decotigny : - Passage en GNU as
027 * David_Decotigny : - Chargement du noyau a 026 * David_Decotigny : - Chargement du noyau au-dela du 1er Mega (taille
028 * max = 0x9e000 octets 027 * max = 0x9e000 octets = 632ko), pour avoir le
029 * meme noyau sous grub 028 * meme noyau sous grub et avec le bootsecteur
030 */ 029 */
031 030
032 /* 031 /*
033 * Sequence d'operations : 032 * Sequence d'operations :
034 * - Le BIOS charge le bootsect en 0x7c00 (BO 033 * - Le BIOS charge le bootsect en 0x7c00 (BOOT_ADRESS). On choisit
035 * la representation 0x7c0:0000 pour que le 034 * la representation 0x7c0:0000 pour que le .org 0 reste valide
036 * - Le bootsect se deplace de lui-meme en 0x 035 * - Le bootsect se deplace de lui-meme en 0x9f000 (COPY_ADRESS). On
037 * choisit la representation 0x9f00:0000 po 036 * choisit la representation 0x9f00:0000 pour que le .org 0 reste
038 * valide 037 * valide
039 * - Le bootsect verifie que le processeur es 038 * - Le bootsect verifie que le processeur est du type 386+
040 * - Il charge le noyau depuis la disquette e 039 * - Il charge le noyau depuis la disquette en memoire a partir de
041 * 0x1000 (LOAD_ADRESS). La place dispo est !! 040 * 0x1000 (LOAD_ADRESS). Le noyau peut au max tenir sur
042 * 0x9E000, soit encore 1264 secteurs de 51 !! 041 * SECTORS_TO_LOAD secteurs
043 * - Il passe en pmode flat (apres ouverture 042 * - Il passe en pmode flat (apres ouverture a20)
044 * - Il recopie le noyau (situe en LOAD_ADRES 043 * - Il recopie le noyau (situe en LOAD_ADRESS) vers son adresse
045 * finale (FINAL_ADDRESS = 2Mo). La recopie 044 * finale (FINAL_ADDRESS = 2Mo). La recopie se fait sur tout l'espace
046 * LOAD_ADRESS ---> COPY_ADRESS, c'est a di 045 * LOAD_ADRESS ---> COPY_ADRESS, c'est a dire sur 0x9e000 octets =
047 * 632ko. Le noyau peut donc au max faire 6 046 * 632ko. Le noyau peut donc au max faire 632ko. Le nombre max de
048 * secteurs de disquette qu'on peut charger 047 * secteurs de disquette qu'on peut charger est donc 1264
049 */ 048 */
050 049
051 050
052 /* La taille de la pile */ 051 /* La taille de la pile */
053 #define BOOT_STACK_SIZE 0x4000 052 #define BOOT_STACK_SIZE 0x4000
054 053
055 .file "bootsect.S" 054 .file "bootsect.S"
056 055
057 /* Tout est place dans une seule secti 056 /* Tout est place dans une seule section */
058 .section ".bootsect" 057 .section ".bootsect"
059 058
060 /* L'essentiel du bootsector (sauf les 059 /* L'essentiel du bootsector (sauf les 1eres instructions)
061 sont a un offset 0. On fait en sort 060 sont a un offset 0. On fait en sorte que le compilo soit
062 d'accord la-dessus. Quand on a des 061 d'accord la-dessus. Quand on a des adresse realm exotiques
063 (0x7c00, 0x9f000, ...), on s'arrang 062 (0x7c00, 0x9f000, ...), on s'arrange toujours pour avoir un
064 offset de 0 => on choisira le segme 063 offset de 0 => on choisira le segment adapte (0x7c0,
065 0x9f00, ...). Il ne faut pas oublie 064 0x9f00, ...). Il ne faut pas oublier le ld -Ttext 0 */
066 .org 0 065 .org 0
067 066
068 /* Pour que gas genere du 16bits, afin 067 /* Pour que gas genere du 16bits, afin que ca marche en realm */
069 .code16 068 .code16
070 069
>> 070 #define SECTORS_TO_LOAD 128 /* 64 ko */ /* MAX=1264 */
>> 071
071 /* 072 /*
072 * Parametres de la disquette. Comme c'est chi 073 * Parametres de la disquette. Comme c'est chiant de faire une
073 * procedure de detection auto, et que ca pren 074 * procedure de detection auto, et que ca prend de la place, on fait
074 * 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
075 * 1.44 Mo a 18 secteurs/pistes 076 * 1.44 Mo a 18 secteurs/pistes
076 */ 077 */
077 #define CYLS 80 078 #define CYLS 80
078 #define HEADS 1 079 #define HEADS 1
079 #define SECTS 18 080 #define SECTS 18
080 081
081 #define BOOT_ADRESS 0x07C00 /* Adre 082 #define BOOT_ADRESS 0x07C00 /* Adresse de demarrage (lineaire) */
082 #define BOOT_SEG (BOOT_ADRESS>>4) /* Segm 083 #define BOOT_SEG (BOOT_ADRESS>>4) /* Segment de Boot */
083 #define BOOT_SIZE 512 /* Tail 084 #define BOOT_SIZE 512 /* Taille bu bootsecteur */
084 #define COPY_ADRESS 0x9F000 /* La o 085 #define COPY_ADRESS 0x9F000 /* La ou on va copier le
085 boot 086 bootsecteur (lineaire) */
086 #define COPY_SEG (COPY_ADRESS>>4) /* Segm 087 #define COPY_SEG (COPY_ADRESS>>4) /* Segment de la ou on va
087 copi 088 copier le bootsecteur */
088 #define LOAD_ADRESS 0x01000 /* 1er 089 #define LOAD_ADRESS 0x01000 /* 1er chargement du systeme */
089 #define LOAD_SEG (LOAD_ADRESS>>4) /* Segm 090 #define LOAD_SEG (LOAD_ADRESS>>4) /* Segment du 1er chargement du */
090 #define MAX_KERN_LEN (COPY_ADRESS-LOAD_ADRESS) !! 091 #define MAX_KERN_LEN COPY_ADRESS-LOAD_ADRESS /* Taille noyau maxi */
091 #define MAX_KERN_SECTS ((MAX_KERN_LEN + 511) > <<
092 092
093 /* IMPORTANT : Cette valeur DOIT etre identiqu 093 /* IMPORTANT : Cette valeur DOIT etre identique a l'adresse presente
094 dans sos.lds ! */ !! 094 dans kos.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 <<
155 /* Verifie que le noyau n'est pas trop <<
156 cmpw $(MAX_KERN_SECTS), (load_size) <<
157 jb sizeOk <<
158 movw $toobig, %si <<
159 call message <<
160 call halt <<
161 <<
162 sizeOk: <<
163 /* Recupere la taille de la RAM */ <<
164 mov $0xE801, %ax <<
165 int $0x15 <<
166 movw %ax, (memsize1) <<
167 movw %bx, (memsize2) <<
168 154
169 /* Affiche les messages d'attente */ 155 /* Affiche les messages d'attente */
170 movw $loadkern, %si 156 movw $loadkern, %si
171 call message 157 call message
172 movw $check, %si 158 movw $check, %si
173 call message 159 call message
174 160
175 check386: 161 check386:
176 /* 162 /*
177 * la attention, plus complexe : on te 163 * la attention, plus complexe : on teste si le proc est un
178 * 386+ pour cela, on va essayer de mo 164 * 386+ pour cela, on va essayer de modifier les bits 12 ? 14
179 * du registre E-flag si la modificati 165 * du registre E-flag si la modification reste, alors le proc
180 * est un 386+, sinon, c'est =< 286 166 * est un 386+, sinon, c'est =< 286
181 * 167 *
182 * Merci a Emmanuel Marty pour la comp 168 * Merci a Emmanuel Marty pour la compatibilite avec les 386
183 * "pre-jurassique" 169 * "pre-jurassique"
184 */ 170 */
185 171
186 pushf /* on sauvegarde le E-Flag */ 172 pushf /* on sauvegarde le E-Flag */
187 movb $0x70, %ah 173 movb $0x70, %ah
188 pushw %ax 174 pushw %ax
189 popf 175 popf
190 pushf 176 pushf
191 popw %ax 177 popw %ax
192 orb %ah, %ah 178 orb %ah, %ah
193 je no386 /* si la modif n'est pas val 179 je no386 /* si la modif n'est pas valable, alors on saute a
194 no386 */ 180 no386 */
195 popf /* on les restaure ? la fin 181 popf /* on les restaure ? la fin ... */
196 182
197 /* Message de confirmation de 386+ et 183 /* Message de confirmation de 386+ et d'attente */
198 movw $found386, %si 184 movw $found386, %si
199 call message 185 call message
200 movw $loading, %si 186 movw $loading, %si
201 call message 187 call message
202 188
203 /* Copie du noyau disquette => RAM a partir de 189 /* Copie du noyau disquette => RAM a partir de 0x1000
204 L'adresse de destination est définie par es 190 L'adresse de destination est définie par es:0, où es vaut
205 initialement 0x100 (ie correspond alors à l 191 initialement 0x100 (ie correspond alors à l'adresse 256*16, soit 4
206 ko). Chaque itération incrémente ce registr 192 ko). Chaque itération incrémente ce registre es de 32, ce qui
207 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
208 secteur. De cette façon, puisqu'on joue sur 194 secteur. De cette façon, puisqu'on joue sur les segments plutôt que
209 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
210 est limitée par contre à la taille de la mé 196 est limitée par contre à la taille de la mémoire disponible sous
211 les 1Mo, \ie 640 ko (0x9f000 - 0x1000). */ 197 les 1Mo, \ie 640 ko (0x9f000 - 0x1000). */
212 copyKernel: 198 copyKernel:
213 /* Chargement du noyau en LOAD_SEG:0 * 199 /* Chargement du noyau en LOAD_SEG:0 */
214 /* 3 iterateurs : 200 /* 3 iterateurs :
215 - load_size : le nbre de secte 201 - load_size : le nbre de secteurs a charger
216 - cl : le secteur ou on en est 202 - cl : le secteur ou on en est pour le
217 cylindre en cours (<= SECTS) 203 cylindre en cours (<= SECTS)
218 - dh : la tete en cours (0/1) 204 - dh : la tete en cours (0/1)
219 */ 205 */
220 movb $0, %dl 206 movb $0, %dl
221 movw $LOAD_SEG, %ax 207 movw $LOAD_SEG, %ax
222 movw %ax, %es 208 movw %ax, %es
223 209
224 xorw %bx, %bx 210 xorw %bx, %bx
225 xorw %dx, %dx 211 xorw %dx, %dx
226 movw $1, %cx /* premier secteur * 212 movw $1, %cx /* premier secteur */
227 213
228 .nextsector: /* prochain secteur * 214 .nextsector: /* prochain secteur */
229 incb %cl /* en incrementant CL 215 incb %cl /* en incrementant CL */
230 cmpb $SECTS, %cl /* si CL =< SECTS (=n 216 cmpb $SECTS, %cl /* si CL =< SECTS (=nbre de secteurs/pistes)
231 alors on charge */ 217 alors on charge */
232 jbe .sector 218 jbe .sector
233 movb $1, %cl /* sinon on revient a 219 movb $1, %cl /* sinon on revient au secteur 1 */
234 incb %dh /* mais sur l'autre t 220 incb %dh /* mais sur l'autre tete */
235 cmpb $1, %dh /* on recompare, si D 221 cmpb $1, %dh /* on recompare, si DH =< 1 */
236 je .sector /* on charge */ 222 je .sector /* on charge */
237 movb $0, %dh /* sinon on repasse a 223 movb $0, %dh /* sinon on repasse a la tete 0 */
238 incb %ch /* mais on change de 224 incb %ch /* mais on change de cylindre */
239 225
240 .sector: 226 .sector:
241 pushw %es 227 pushw %es
242 movw $0x0201, %ax /* service 0x2, char 228 movw $0x0201, %ax /* service 0x2, chargement 0x1 seecteur */
243 int $0x13 /* Go ! */ 229 int $0x13 /* Go ! */
244 jc halt /* erreur */ 230 jc halt /* erreur */
245 popw %ax 231 popw %ax
246 addw $32, %ax /* on a charge un se 232 addw $32, %ax /* on a charge un secteur, donc on doit
247 charger 512 bytes 233 charger 512 bytes plus loin */
248 movw %ax, %es /* on avance donc le 234 movw %ax, %es /* on avance donc le segment du buffer de
249 32bytes, ie 1 sec 235 32bytes, ie 1 secteur en RAM (car 32*16=512) */
250 236
251 movw $(0x0E*256+'.'), %ax /* affiche u 237 movw $(0x0E*256+'.'), %ax /* affiche un point */
252 int $0x10 238 int $0x10
253 239
254 decw (load_size) /* et on repart p 240 decw (load_size) /* et on repart pour le prochain secteur
255 tant qu'on n'a pa 241 tant qu'on n'a pas fini ! */
256 jnz .nextsector 242 jnz .nextsector
257 243
258 after: 244 after:
259 movw $0x03f2, %dx 245 movw $0x03f2, %dx
260 inb %dx, %al /* stoppe le moteur */ 246 inb %dx, %al /* stoppe le moteur */
261 andb $0x0f, %al 247 andb $0x0f, %al
262 outb %al, %dx 248 outb %al, %dx
263 249
264 cli /* on interdit les i 250 cli /* on interdit les interruptions */
265 251
266 fincopie: 252 fincopie:
267 pushw %cs 253 pushw %cs
268 popw %ds 254 popw %ds
269 255
270 /* on ouvre la porte A20 */ 256 /* on ouvre la porte A20 */
271 WAITKB /* on vide le buffer 257 WAITKB /* on vide le buffer */
272 movb $0xd1, %al /* on met a jour le po 258 movb $0xd1, %al /* on met a jour le port */
273 outb %al, $0x64 259 outb %al, $0x64
274 WAITKB 260 WAITKB
275 movb $0xdf, %al /* bit 2 = ouverture/f 261 movb $0xdf, %al /* bit 2 = ouverture/fermeture */
276 outb %al, $0x60 262 outb %al, $0x60
277 263
278 /* 264 /*
279 * init gdt 265 * init gdt
280 */ 266 */
281 InitGDT: 267 InitGDT:
282 /* Préparation du flat mode */ 268 /* Préparation du flat mode */
283 lgdt gdtr 269 lgdt gdtr
284 270
285 GoPMode: 271 GoPMode:
286 /* Passage en mode protégé */ 272 /* Passage en mode protégé */
287 movl %cr0, %eax 273 movl %cr0, %eax
288 orb $1, %al /* set PE bit to 1 */ 274 orb $1, %al /* set PE bit to 1 */
289 movl %eax, %cr0 275 movl %eax, %cr0
290 276
291 /* we are not yet in Pmode jump 'in' p 277 /* we are not yet in Pmode jump 'in' pmode clearing prefetch
292 * queue and loading a new selector */ 278 * queue and loading a new selector */
293 movw $0x10, %ax 279 movw $0x10, %ax
294 movw %ax, %ds 280 movw %ax, %ds
295 movw %ax, %es 281 movw %ax, %es
296 movw %ax, %fs 282 movw %ax, %fs
297 movw %ax, %gs 283 movw %ax, %gs
298 284
299 /* 285 /*
300 * Code 32 bits ============================== 286 * Code 32 bits ============================================================
301 */ 287 */
302 .code32 288 .code32
303 289
304 JumpToHere32: /* Se deplace a l'endroit actuel 290 JumpToHere32: /* Se deplace a l'endroit actuel, en passant en 32bits
305 et en utilisant la gdt, et vi 291 et en utilisant la gdt, et vide la prefetch queue */
306 .byte 0x66 /* Prefixe 32bits : en real 292 .byte 0x66 /* Prefixe 32bits : en realite, jusqu'au jmp, on est
307 encore en 16 bits */ 293 encore en 16 bits */
308 ljmp $0x8, $(COPY_ADRESS+(Here32)) 294 ljmp $0x8, $(COPY_ADRESS+(Here32))
309 Here32: 295 Here32:
310 /* Et voila : On est en 32 bits vrai * 296 /* Et voila : On est en 32 bits vrai */
311 297
312 MoveKernelToFinalAddr: /* Deplace le noyau (en 298 MoveKernelToFinalAddr: /* Deplace le noyau (en LOAD_ADDRESS) vers sa
313 destination finale ( 299 destination finale (FINAL_ADDRESS) */
314 movl $0x10, %eax 300 movl $0x10, %eax
315 movl %eax, %ds /* Seg Src = DSeg */ 301 movl %eax, %ds /* Seg Src = DSeg */
316 movl %eax, %es /* Sed Dest = DSeg */ 302 movl %eax, %es /* Sed Dest = DSeg */
317 cld 303 cld
318 movl $LOAD_ADRESS, %esi /* On comme 304 movl $LOAD_ADRESS, %esi /* On commence la copie au debut du noyau */
319 movl $FINAL_ADDRESS, %edi /* On copie 305 movl $FINAL_ADDRESS, %edi /* On copie vers cette adresse */
320 movl $MAX_KERN_LEN, %ecx /* Taille r 306 movl $MAX_KERN_LEN, %ecx /* Taille recopie */
321 shrl $2, %ecx 307 shrl $2, %ecx
322 rep 308 rep
323 movsl 309 movsl
324 310
325 LaunchKernel: 311 LaunchKernel:
326 /* Met en place une pile au niveau du 312 /* Met en place une pile au niveau du symbole "stack" */
327 movl %eax, %ss 313 movl %eax, %ss
328 movl $(stack + BOOT_STACK_SIZE), %ebp 314 movl $(stack + BOOT_STACK_SIZE), %ebp
329 movl %ebp, %esp 315 movl %ebp, %esp
330 <<
331 /* passe les arguments a sos */ <<
332 xor %eax, %eax <<
333 xor %ebx, %ebx <<
334 movw (COPY_ADRESS+(memsize2)), %ax /*e <<
335 movw (COPY_ADRESS+(memsize1)), %bx /*e <<
336 movl $0x40, %ecx /*ecx=64 */ <<
337 mul %ecx <<
338 add %ebx, %eax <<
339 pushl %eax /* valeur de addr */ <<
340 pushl $0x42244224 /* valeur de magic p <<
341 la taille de la R <<
342 pushl $0 /* normalement call fait un p <<
343 316
344 /* Saut vers le noyau. La GDT est en p 317 /* Saut vers le noyau. La GDT est en place (flat mode), les
345 * selecteurs aussi, a20 est ouverte, 318 * selecteurs aussi, a20 est ouverte, et les interruptions sont
346 * cli + pas de idt. Le PIC n'est pas 319 * cli + pas de idt. Le PIC n'est pas programme */
347 ljmp $0x8, $sos_main 320 ljmp $0x8, $sos_main
348 321
349 /* 322 /*
350 * Utilities ================================= 323 * Utilities ============================================================
351 */ 324 */
352 .code16 325 .code16
353 326
354 message: 327 message:
355 lodsb /* charge ds:si dans 328 lodsb /* charge ds:si dans al et incremente si */
356 orb %al, %al /* si al = 0 */ 329 orb %al, %al /* si al = 0 */
357 jz 1f 330 jz 1f
358 movb $0x0e, %ah /* service 0Eh (affi 331 movb $0x0e, %ah /* service 0Eh (affichage d'un caractere) */
359 movw $0x0007, %bx /* Parametres : blan 332 movw $0x0007, %bx /* Parametres : blanc sur fond noir */
360 int $0x10 /* Appel de l'inter 333 int $0x10 /* Appel de l'interruption 10h */
361 jmp message /* On repart au débu 334 jmp message /* On repart au début ... */
362 1: ret /* si la chaine est 335 1: ret /* si la chaine est finie alors on retourne
363 dans la fonction 336 dans la fonction appelante */
364 337
365 halt: 338 halt:
366 pushw %cs 339 pushw %cs
367 popw %es 340 popw %es
368 movw $haltmsg, %si 341 movw $haltmsg, %si
369 call message 342 call message
370 cli 343 cli
371 1: jmp 1b 344 1: jmp 1b
372 ret 345 ret
373 346
374 no386: 347 no386:
375 movw $need386, %si 348 movw $need386, %si
376 call message 349 call message
377 call halt 350 call halt
378 351
379 /* 352 /*
380 * GDT 353 * GDT
381 */ 354 */
382 355
383 gdt: 356 gdt:
384 gdtr: 357 gdtr:
385 NULL_Desc: 358 NULL_Desc:
386 .word (EndGDT)-(gdt)-1 /* Taille GDT * 359 .word (EndGDT)-(gdt)-1 /* Taille GDT */
387 .long (gdt)+COPY_ADRESS 360 .long (gdt)+COPY_ADRESS
388 unused: 361 unused:
389 .word 0 362 .word 0
390 363
391 CS_Desc: /* 0x8 */ 364 CS_Desc: /* 0x8 */
392 .word 0xFFFF, 0 365 .word 0xFFFF, 0
393 .byte 0, 0x9B, 0xCF, 0 366 .byte 0, 0x9B, 0xCF, 0
394 367
395 DS_Desc: /* 0x10 */ 368 DS_Desc: /* 0x10 */
396 .word 0xFFFF, 0 369 .word 0xFFFF, 0
397 .byte 0, 0x93, 0xCF, 0 370 .byte 0, 0x93, 0xCF, 0
398 371
399 EndGDT: 372 EndGDT:
400 373
401 /* quelques messages */ 374 /* quelques messages */
402 375
403 loadkern: .string "This is SOS\r\n" !! 376 loadkern: .string "-= S O S =- : The Simple Operating System \r\n"
404 toobig: .string "Image too big\r\n" !! 377 check: .string "Checking for a 386+ processor... "
405 check: .string "Checking 386+ process <<
406 found386: .string " [OK]\r\n" 378 found386: .string " [OK]\r\n"
407 need386: .string " [FAILED]\r\n" 379 need386: .string " [FAILED]\r\n"
408 diskerror: .string "Disk Error\r\n" 380 diskerror: .string "Disk Error\r\n"
409 loading: .string "Loading... " 381 loading: .string "Loading... "
410 haltmsg: .string "System Halted\r\n" 382 haltmsg: .string "System Halted\r\n"
411 383
412 /* Variables pour stocker la taille de la <<
413 memsize1: .long 0 <<
414 memsize2: .long 0 <<
415 <<
416 /*** Les code/données du boot secteur se termi 384 /*** Les code/données du boot secteur se terminent ICI. le marqueur de
417 * fin (aa55) est ajouté automatiquement par l 385 * fin (aa55) est ajouté automatiquement par le script ld
418 * sos_bsect.lds ***/ 386 * sos_bsect.lds ***/
419 387
420 /* 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
421 declaree avec le noyau, dans sa section ".i !! 389 declaree avec le noyau, dans sa section ".bss", cad HORS du boot
422 secteur ! (sinon ca depasserait 512B, forcé 390 secteur ! (sinon ca depasserait 512B, forcément). On aurait pu la
423 définir directement dans le sos_bsect.lds, 391 définir directement dans le sos_bsect.lds, ou dans un fichier .c
424 auxiliaire pour plus de clarté */ 392 auxiliaire pour plus de clarté */
425 /* Here is the stack */ !! 393 .comm stack, BOOT_STACK_SIZE
426 .section ".init_stack", "aw", @nobits <<
427 .p2align 4 <<
428 .size stack, BOOT_STACK_SIZE <<
429 stack: <<
430 .space BOOT_STACK_SIZE <<
431 <<
432 /* Some data characterizing the stack addresse <<
433 .data <<
434 .globl bootstrap_stack_bottom <<
435 bootstrap_stack_bottom: .long stack <<
436 <<
437 .globl bootstrap_stack_size <<
438 bootstrap_stack_size: .long BOOT_STACK_SIZE <<