10
votes

Comment charger le chargeur de démarrage de la deuxième étape de la première étape?

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 commentaires

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)


3 Réponses :


8
votes

sur x86, vous feriez ce qui suit (simplifié):

  • Demandez au chargeur de démarrage du N-ème secteur du disque / la disquette (partout où vous démarrez) dans la mémoire et exécutez-le (c'est-à-dire segment de charge / décalage et repor ). 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).
  • 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) .
  • L'assemblage de noyau 32 bits, puis définit simplement extern _mykernel (par exemple) et appelle ce symbole.
  • Ensuite, vous pouvez commencer à écrire votre noyau sous forme C mykernel .

    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:


0 commentaires

1
votes

Regardez la mise en œuvre de la grub ici (étape 1):

http://src.illumos.org/source/xref/illumos-gate/usr/src/grub/grUB-0.97/stage1/stage1.s

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


1 commentaires

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?



2
votes

6 commentaires

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 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 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 à zéro, donc je ferais un JMP 0x0000: étape2 . 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 est également zéro depuis n'importe quel code qui s'appuie sur ds une valeur spécifique peut ne pas fonctionner Correctement dans les environnements où le BIOS peut avoir défini DS à autre chose.


De plus, je ne vous recommande pas de définir dl à 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.