SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

Diff markup

Differences between /extra/bootsect.S (Article 9) and /extra/bootsect.S (Article 4)


001                                                   001 
002 /*                                                002 /*
003  * @(#) $Id: bootsect.S,v 1.12 2005/08/13 13:4 !! 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 (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 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                                                << 
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    << 
                                                      

source navigation ] diff markup ] identifier search ] general search ]