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 2) and /extra/bootsect.S (Article 9.5)


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