J'ai écrit simple premier chargeur de démarrage de premier étage qui affiche "Hello World" en utilisant une interruption au BIOS. Maintenant, comme une étape évidente suivante pour écrire une deuxième étape, mais où le code pour cela devrait exister et comment le charger de la première étape?
Voici un programme de première étape P>
[BITS 16] ;Tells the assembler that its a 16 bit code [ORG 0x7C00] ;Origin, tell the assembler that where the code will ;be in memory after it is been loaded MOV SI, HelloString ;Store string pointer to SI CALL PrintString ;Call print string procedure JMP $ ;Infinite loop, hang it here. PrintCharacter: ;Procedure to print character on screen ;Assume that ASCII value is in register AL MOV AH, 0x0E ;Tell BIOS that we need to print one charater on screen. MOV BH, 0x00 ;Page no. MOV BL, 0x07 ;Text attribute 0x07 is lightgrey font on black background INT 0x10 ;Call video interrupt RET ;Return to calling procedure PrintString: ;Procedure to print string on screen ;Assume that string starting pointer is in register SI next_character: ;Lable to fetch next character from string MOV AL, [SI] ;Get a byte from string and store in AL register INC SI ;Increment SI pointer OR AL, AL ;Check if value in AL is zero (end of string) JZ exit_function ;If end then return CALL PrintCharacter ;Else print the character which is in AL register JMP next_character ;Fetch next character from string exit_function: ;End label RET ;Return from procedure ;Data HelloString db 'Hello World', 0 ;HelloWorld string ending with 0 TIMES 510 - ($ - $$) db 0 ;Fill the rest of sector with 0 DW 0xAA55 ;Add boot signature at the end of bootloader
3 Réponses :
sur x86, vous feriez ce qui suit (simplifié): p>
repor code>). Une meilleure alternative consiste à rechercher le système de fichiers pour un certain nom de fichier (par exemple kernel.bin) - mais vous devez connaître le type de système de fichiers (par exemple FAT12 si vous testez à partir d'une image de disquette). LI>
- Le noyau commencerait alors en mode réel. Il définit les descripteurs de code, GDT, etc., active l'adressage 32 bits (vous avez dû entendre parler de "A20") et entre enfin en mode protégé. Ensuite, vous avez besoin d'un coup de poing sur un segment de code 32 bits (le fichier de noyau doit être associé de manière à ce que le code 32 bits soit à une position absolue, par exemple à la décalage 512, juste après le mode de mode réel 16 bits) . li>
- L'assemblage de noyau 32 bits, puis définit simplement
extern _mykernel code> (par exemple) et appelle ce symbole. Li>
- Ensuite, vous pouvez commencer à écrire votre noyau sous forme C
mykernel code>. li>
ul>
Ok ce fut un bref aperçu de ce que j'ai fait il y a quelques années (avec beaucoup de copie et de pâte d'Internet;). Si cela n'est pas utile, voici quelques bonnes ressources Web sur le développement du système d'exploitation: P>
Regardez la mise en œuvre de la grub ici (étape 1):
a d'abord remarqué le point de départ à 0x7C00 et la signature de fin de 0xaa55 pour ce premier secteur. De l'intérieur du démontage, vous pouvez voir ceci: p>
349 copy_buffer:
350 movw ABS(stage2_segment), %es
351
352 /*
353 * We need to save %cx and %si because the startup code in
354 * stage2 uses them without initializing them.
355 */
356 pusha
357 pushw %ds
358
359 movw $0x100, %cx
360 movw %bx, %ds
361 xorw %si, %si
362 xorw %di, %di
363
364 cld
365
366 rep
367 movsw
368
369 popw %ds
370 popa
371
372 /* boot stage2 */
373 jmp *(stage2_address)
374
375 /* END OF MAIN LOOP */
376
Comment l'assembleur sait-il que toutes les étiquettes du code chargées du disque sont désormais décalées par partout où vous avez chargé dans la RAM?
Minimal Runnable NASM BIOS Exemple qui charge l'étage 2 et se saute à celui-ci fort> compiler et exécuter: p> Résultat attendu: testé sur Ubuntu 14.04. P> Exemple de gaz SANER utilisant un Script de liaison et initialisation plus correcte (registres de segment, pile) sur mon github . p> p> A code> est imprimé sur l'écran, puis le programme s'arrête. p>
Si quelqu'un peut deviner pourquoi le bowvote, s'il vous plaît, pour que je puisse apprendre et améliorer les informations. Je ne fais jamais de représailles.
Ah, je regarde via la liste Active "code> bootloader code> tag et je vois que nous nous rencontrons. Une observation que je vais faire est que j'aurais probablement refermé cette question aussi large. Bien que vous fournissiez une solution, vous affirmez que l'OP ne ferait que charger du prochain secteur après le MBR. Bien que ce soit une solution, je pense que la principale marque est plus proche de la marque de discuter d'autres idées comme faire une recherche de fichier pour le système de fichiers. Cette réponse suppose également une grande chose - existe-t-il un système de fichiers contenant la 2ème étape? Quel système de fichiers est-ce? etc...
@MichaelPetch hey là encore :-) J'ai convenu que c'est une bonne réponse. C'est juste que j'aimerais d'abord avoir d'abord des choses à suivre pour voir la beauté de celle-ci: et il est ensuite plus facile de comprendre les pièces plus profondes plus tard.
Vous devez vous assurer que le registre ES i> est de zéro car le INT13H / AH = 2H est utilisé pour l'adresse tampon. Je prendrais probablement aussi l'opportunité d'utiliser le stade JMP2 pour définir CS i> à zéro, donc je ferais un JMP 0x0000: étape2 code>. Je pense que la complétude au moment où vous êtes dans la scène2, vous devriez les faire en train de vous assurer que DS i> est également zéro depuis n'importe quel code qui s'appuie sur ds i> une valeur spécifique peut ne pas fonctionner Correctement dans les environnements où le BIOS peut avoir défini DS i> à autre chose.
De plus, je ne vous recommande pas de définir dl i> à un numéro de lecteur fixe. Vous devez simplement utiliser celui qui est passé du BIOS lorsque le transfert a été contrôlé au chargeur de démarrage.
Et puisque vous lisez des secteurs dans la RAM, vous devez configurer SS: SP dans un emplacement que vous savez spécifiquement ne sera pas classé par le disque en lecture. Si la pile devient en croissance 0x8000 vers 0x7e00, votre pile peut finir par collision avec votre deuxième étape. Il est plus simple de déplacer la pile où vous savez qu'il n'y a pas d'interférence.
Utilisez-vous le langage C? Avez-vous d'autres informations sur l'importance que vous pouvez partager?
Nous avons utilisé des instructions de l'Assemblée X86 pour la première étape, mais nous prévoyons d'écrire une deuxième étape dans une langue de niveau supérieur comme c .. Où puis-je stocker cette deuxième étape binaire et comment le charger du chargeur de démarrage de première étape
Dupliqué possible de Chargement du nez de l'assemblage (NasM)