Créez votre propre disquette d'amorçage

Gazette Linux n°084 - novembre 2002

par Muhammad Torabi Dashti (Copyright © 2002) <mtdashti AT mehr DOT sharif DOT edu>

traduction française par Sébastien Marbrier (tous droits réservés) <sebastien DOT marbrier AT laposte DOT net>


Table des matières :

Introduction

En lisant un fascinant article dans le numéro 77 de la Gazette Linux, Écrivez votre micro OS (1ère partie) de Krishnakumar R. [1]; j'ai vu une bizarrerie, les deux derniers octets du secteur d'amorçage devraient contenir 0x55AA! Et comme le prouve les commentaires de cet article, je n'étais pas le seul à jouer avec les valeurs magiques. J'ai donc réécris le secteur d'amorçage de Krishnakumar avec nasm [2] (je ne connais pas as86) et j'ai supprimé de write.c la ligne insérant 0x55AA. Et que s'est-il passé ? Mon PC a démarré ! Alors pourquoi Krishnakumar a t-il écrit cette partie ? Ou plus généralement, qui lit le secteur d'amorçage ? La réponse est simple : Le BIOS ! Un autre point intéressant et qu'IBM a publié le code source du BIOS de son XT dans La Référence Technique du XT [3]. Jetons-y un coup d'oeuil : (J'y ai apporté quelques modifications, il n'est pas aussi complet que l'original)

Code d'amorçage du XT

;---INT 19H
BOOT_STRAP:
;INITIALISATIONS
        MOV CX,3        ;COMPTEUR DE REPRISES
H1:
        PUSH CX
        SUB DX,DX
        SUB AX,AX
        INT 13H ;INITIALISATION DISQUETTE
        JC H2
        MOV AX,0201H
        SUB DX,DX
        MOV ES,DX
        ;BOOT_LOCN A ETE DEFINIE PRECEDEMMENT
        ;ORG 7C00H
        ;BOOT_LOCN LABEL FAR
        MOV BX, OFFSET BOOT_LOCN
        MOV CX,1
        INT 13H ;LIT LE SECTEUR 0 DE LA DISQUETTE
H2:
        POP CX
        JNC H4
        CMP AH,80H      ;VERIFIE L'EXPIRATION DU COMPTEUR
        JZ H5
        LOOP H1
        JMP H5
H4:
        JMP BOOT_LOCN
H5:
        ;RECHERCHE D'UN DISQUE DUR
        SUB AX,AX
        SUB DX,DX
        INT 13H
        MOV CX,3
H6:
        PUSH CX
        MOV DX,0080H
        SUB AX,AX
        INT 13H
        JC H7
        MOV AX,0201H
        SUB BX,BX
        MOV ES,BX
        MOV BX,OFFSET BOOT_LOCN
        MOV DX,80H
        MOV CX,1
        INT 13H
H7:
        POP CX
        JC H8
        MOV AX, WORD PTR BOOT_LOCN+510D
        CMP AX,0AA55H   ;NOMBRE MAGIQUE!
        JZ H4
H8:
        LOOP H6
        INT 18H ;ECHEC COMPLET!

Très bien ! Tout est clair à présent. Cette valeur 0x55AA est testée seulement si le secteur d'amorçage est chargé depuis un disque dur, Krishnakumar l'a donc utilisée pour s'assurer de la compatibilité. Notez également que toute chaîne aléatoire de bits dans le secteur 0 d'une disquette est considérée comme un secteur d'amorçage et le système l’exécute !

Mais j'utilise un Windows 2000 en plus de mon Linux et mes disquettes ont toujours un système de fichier msdos (fat 12) pour que chaque système d'exploitation puisse les lire. Faisons à présent une expérience simple : formatons une disquette avec Windows (ou tout système d'exploitation basé sur le DOS) et laissons l'ordinateur démarrer avec cette disquette. Vous verrez un message indiquant que la disquette n'est pas amorçable et vous demandant de la remplacer et d'appuyer sur une touche. C'est également la même chose lorsque l'on formatte la disquette sous Linux et que l'on utilise un système de fichers msdos (on peut utilise la commande mkfs -V -t msdos /dev/fd0, ou bien l'utilitaire de formatage de disquettes de KDE). Cela devient encore plus étrange quand on utilise le système de fichier ext2 sur la disquette (#mkfs -V -t ext2 /dev/fd0). L'ordinateur ne traitement pas la disquette et transfère simplement le contrôle au secteur d'amorçage du disque dur (ex. LiLo). Alors quelle est la différence entre ces deux formats et notre disquette de démarrage ? J'ai modifié le write.c de Krishnakumar et le read.c lit le secteur d'amorçage d'une disquette et le copie dans le fichier boot.sec; il l'affiche aussi élégamment. Vous pouvez, si vous le souhaiter, utiliser les outils Linux pour la même chose: pour écrire le secteur d'amorçage sur la disquette (#dd if=boot.sec of=/dev/fd0 bs=1 count=512) et pour le lire (#dd if=boot.sec of=/dev/fd0 bs=1 count=512 skip=0).

Observez le secteur d'amorçage d'un ext2. Il n'y a que des zéros ! Mais le secteur d'amorçage msdos contient quelques instructions. Désassemblons-le (j'utilise ndisasm[2]):

1. insérez une disquette au format msdos.

2. exécutez "./read"

3. exécutez "ndisasm boot.sec | more"

4. la première instruction est un saut à l'adresse 0x3e mais le code n'est pas correctement indenté.

5. exécutez "ndisasm -s 0x3e boot.sec | more" pour voir le code indenté.

OK, nous avons donc ici un minuscule secteur d'amorçage, il se contente d'afficher un message (le message dépend du système d'exploitation, et vous pouvez le modifier au moyen d'un éditeur binaire quelconque, tels que ceux de KDE. A titre d'exemple, modifions boot.sec afin d'afficher un message amusant et réécrivons-le en utilisant le write.c de Krishnakumar's write.c sur la disquette !) attendons ensuite un touche et invoquons à nouveau l'interruption 0x19 (la procédure du BIOS boot_starp). En réalité, MS DOS utilisait l'espace entre le saut et l'adresse 0x3e pour stocker des informations (la FAT) et cette méthode fut perpétuée par ses successeurs; c'est pour cela qu'il y a un saut ici. Vous trouverez des informations sur le système de fichier MS-DOS sur le net ou bien vous pouvez consulter [4].

Jusqu'ici, tout est logique, le BIOS se contente d’exécuter tout ce qu'il trouve sur le secteur d'amorçage, ce peut être notre exemple "écris un 'A' et c'est tout" ou bien un élégant secteur d'amorçage tel que celui de MS DOS. Mais lorsque j'ai désassemblé le secteur d'amorçage ext2, rien n'était clair. C'est remplit de zéros ce qui implique la présence de nombreuses instructions ADD inutiles ! Pourquoi le BIOS le passe t-il et ne reste pas bloqué dedans ? Tout simplement parce que le BIOS à changé entre le XT et le AT ! J'ai trouvé un code source du BIOS AT sur le net (il n'y a malheureusement aucune référence, mais il est probable que la Référence Technique de l'IBM AT contienne également ce code d'amorçage.)

Code d'amorçage de l'AT

;---INT  19H
BOOT_STRAP_1    PROC    NEAR
;INITIALISATIONS
;PURGE @BOOT_LOCN
        STI
        MOV     CX,4
H1:     PUSH    CX
        KTOV    AH,0
        INT     13H
        JC      H2
        MOV     AX,201H
        SUB     DX,DX
        MOV     ES,DX
        MOV     SX,OFFSET @BOOT_LOCN
        MOV     CX,1
        INT     13H
H2:     POP     CX
        JNC     H4
        CMP     AH,80H
        JZ      H5
        LOOP    H1
        JMP     SHORT H5
H4:     CMP     BYTE PTR @BOOT_LOCN,06H ;TEST#1
        JB      H10
        MOV     DI,OFFSET @BOOT_LOCN
        MOV     CX,8
        MOV     AX,WORD PTR @BOOT_LOCN
H4A:    ADD     DI,2
        CMP     AX,[DI] ;TEST#2
        LOOPZ   H4A
        JZ      H10
H4_A:   JMP     @BOOT_LOCN
H5:     
        ;INTIALISATIONS ET PRE-TESTS
        SUB     AX,AX
        SUB     DX,DX
        INT     13H
        MOV     CX,3
H6:
        PUSH    CX
        MOV     DX,0080H
        MOV     AX,0201H
        SUB     BX,BX
        MOV     ES,BX
        MOV     BX,OFFSET @BOOT_LOCN
        MOV     CX,1
        INT     13H
        POP     CX
        JC      H8
        CMP     WORD PTR @BOOT_LOCN+510D,0AA55H ; NOMBRE MAGIQUE!
        JZ      H4_A
H8:     PUSH    CX
        MOV     DX,0080H
        SUB     AX,AX
        INT     13H
        POP     CX
        JC      H10A
        LOOP    H6
H9:     
        ;PARTIE QUI NE NOUS INTERESSE PAS
        INT     18H
H10A:   LOOP    H8
        JMP     H9
H10:    ;AFFICHE UN MESSAGE
H11:    jmp H11
BOOT_STRAP_1    ENDP

Deux nouveaux tests sont ajoutés au secteur d'amorçage de la disquette:

1. Son premier octet doit être supérieur à 0x6 ! Celà signifie que la première instruction ne peut être ADD (les OpCode 0 à 5 sont utilisées par les différents modes de different modes de ADD). La raison est logique; aucun programmeur responsable ne voudrait additionner des valeurs inconnues du registre au démarrage. Et c'est pour cela (tel que dans le cas du ext2) un message s'affiche et le PC attend un redémarrage. L'énigme est partiellement résolue ! Sur mon PC, le contrôle est donné au secteur de démarrage du disque dur. C'est bien entendu préférable, de nos jours presque tous les PC ont un disque dur. Il est possible que le BIOS a changé depuis les premiers AT.

2. Ses huit premiers mots ne peuvent être identiques, je n'en connais pas la raison; mais il semblerait que ce soit purement arbitraire. Vous pouvez facilement faire le test en ajoutant 16 NOP (0x90) au secteur d'amorçage de Krishnakumar, vous verrez que votre PC ne démarrera pas !

Vous pouvez soit utiliser ces outils (read.c and write.c) ou bien les outils de Linux (par ex. l'adorable commande 'dd') pour investiguer dans la structure des secteurs d'amorçage. Voici une expérience intéressante pour quiconque ayant Windows et Linux installés côte-à-côte et qui utilisent LiLo en tant que gestionnaire d'amorçage (installé sur le MBR): réalisez un menu de démarrage récursif ! Les étapes sont les suivantes :

1. utilisez 'dd' ou 'read.c' pour lire le MBR: #dd if=/dev/hda of=mbr.sec bs=1 count=512 skip=0

2. copiez mbr.sec sur votre partition amorçable de Windows (presque toujours c:\). Vous pouvez utiliser les élégants programmes de John Newbigin si toutes vos tentatives échouent.

3. éditez boot.ini en ajoutant à la fin une ligne telle que : c:\mbr.sec = "LiLo Again!"

Et le processus de démarrage se poursuit...

Références

[1]http://www.tldp.org/LDP/LG/issue77/krishnakumar.html

[2]http://nasm.sourceforge.net/

[3]IBM, "IBM Personal Computer XT Technical Reference", Vol.2,1981.

[4]M.A.Mazidi, J.G.Mazidi, "The 80X86 IBM PC & Compatible Computers",Vol.2, Prentice Hall, 1995.


Adaptation française de la Gazette Linux

L'adaptation française de ce document a été réalisée dans le cadre du Projet de traduction de la Gazette Linux

Cet article est publié selon les termes de la Open Publication License. La Linux Gazette n'est ni produite, ni sponsorisée, ni avalisée par notre hébergeur principal, SSC, Inc.

Vous pourrez lire d'autres articles traduits et en apprendre plus sur ce projet en visitant notre site http://www.traduc.org/Gazette_Linux

Si vous souhaitez apporter votre contribution, n'hésitez pas à nous rejoindre, nous serons heureux de vous accueillir.