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 9.5)


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

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