Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Prochaine révision
Révision précédente
la_partie_executable_du_mbr [Le 20/04/2011, 14:11]
Nasman créée
la_partie_executable_du_mbr [Le 20/12/2021, 19:22] (Version actuelle)
wiki-corrector-bot passage de http à https sur les liens externes (détecté et corrigé via le bot wiki-corrector (https://forum.ubuntu-fr.org/viewtopic.php?id=2067892)
Ligne 1: Ligne 1:
 +
 . .
-{{tag> tutoriel mbr}}+{{tag> tutoriel mbr BROUILLON}}
 ---- ----
  
 ====== Que trouve-t-on comme programme dans le mbr ====== ====== Que trouve-t-on comme programme dans le mbr ======
  
-Si vous êtes arrivés sur cette page par erreur, faites demi tour sans tarder car ici se trouve l'​antre de la bête - et il ne faut pas connaitre ​la peur car vous allez découvrir les entrailles de votre machine. ​+Si vous êtes arrivés sur cette page par erreur, faites demi tour sans tarder car ici se trouve l'​antre de la bête :-( - où il ne faut pas connaître ​la peur car vous allez découvrir les entrailles de votre machine. ​8-o
 \\ \\
 Le mbr est le premier secteur du disque chargé en mémoire lors du démarrage d'un ordinateur. Il a pour fonction principale de rechercher une partition où se trouve un système d'​exploitation à lancer. Le mbr est le premier secteur du disque chargé en mémoire lors du démarrage d'un ordinateur. Il a pour fonction principale de rechercher une partition où se trouve un système d'​exploitation à lancer.
Ligne 16: Ligne 17:
   * Connaitre la numération hexadécimale.   * Connaitre la numération hexadécimale.
   * Connaitre le langage assembleur   * Connaitre le langage assembleur
-  * Avoir installé un assembleur/​désassembleur comme le paquet nasm+  * Avoir installé un assembleur/​désassembleur comme le paquet ​[[apt>nasm]]
    
 ===== Que se passe-t-il au démarrage d'un PC ? ===== ===== Que se passe-t-il au démarrage d'un PC ? =====
Ligne 29: Ligne 30:
 \\ \\
 Une fois le chargement terminé et sans erreur, l'​exécution se poursuit à l'​adresse 0000:7C00, et donc suit les instructions qui figurent dans le premier secteur du mbr Une fois le chargement terminé et sans erreur, l'​exécution se poursuit à l'​adresse 0000:7C00, et donc suit les instructions qui figurent dans le premier secteur du mbr
 +\\ 
 +<note tip>Lors d'un démarrage en mode UEFI avec un disque GPT, le mbr (protector) ne semble quasiment pas utilisé et seul l'​emplacement de l'​en-tête GPT est nécessaire (unique entrée de la table des partitions du mbr protector)</​note>​
 ===== Comment accéder à ces informations ===== ===== Comment accéder à ces informations =====
  
Ligne 52: Ligne 54:
 Le résultat brut pose problème car des chaines de texte ont été considérées comme des instructions et sont donc mal interprétées. Il faut alors procéder par tâtonnement pour les repérer (par exemple avec un éditeur hexa) et les exclure du traitement de désassemblage. Le résultat brut pose problème car des chaines de texte ont été considérées comme des instructions et sont donc mal interprétées. Il faut alors procéder par tâtonnement pour les repérer (par exemple avec un éditeur hexa) et les exclure du traitement de désassemblage.
 \\ \\
-Une autre difficulté est que certaines adresses peuvent contenir, soit du code à un moment donné, soit des données (zone tampon) lorsque ​que le code n'est plus utilisé.+Une autre difficulté est que certaines adresses peuvent contenir, soit du code à un moment donné, soit des données (zone tampon) lorsque le code n'est plus utilisé. 
 + 
 +===== Exemple de zone exécutable d'un mbr ===== 
 + 
 +L'​exemple qui suit concerne un mbr obtenu lors de l'​installation de Lucid. Lucid a été installé en mettant grub-pc dans le mbr. 
 +\\ 
 +J'ai effectué une analyse (partielle) du fonctionnement des différents morceaux mais des parties restent encore nébuleuses. 
 +\\ 
 +Le programme utilise des fonctions du bios (seules fonctions disponibles à ce stade du démarrage du PC) et je me suis servi de la liste des [[http://​www.ctyme.com/​intr/​int.htm|interruptions]] 
 + ​établies par Ralph Brown. 
 +\\ 
 +\\ 
 +Voilà donc à quoi ressemble la chose. 
 +\\ 
 +<​code>;​ Programme 16 bits chargé en 0000:7C00 
 +00000000 ​ EB63              jmp short 0x65 
 +00000002 ​ 90                nop 
 +00000003 ​ D0 
 +00000004 resb 1 ; mode : 0x00 pour le mode CHS, 0x01 pour le mode LBA 
 + 
 +; Buffer pour chargement en mode CHS 
 +00000005 resd 1 ; nombre de secteurs 
 +00000009 resd 1 ; nombre de têtes 
 +0000000D resd 1 ; nombre de cylindres 
 + 
 +; Buffer pour chargement en mode LBA 
 +00000005 ​         resw 1 ; 0x0010 - taille paquet 
 +00000007 resw 1 ; 0x0001 - nb blocs à transférer 
 +00000009 resw 1 ; 0x0000 
 +0000000B resw 1 ; 0x7000 - buffer en 0x70000000 
 +0000000D resd 1 ; 0x00000001 - emplacement LBA du bloc à charger 
 +00000011 resd 1 ; 0x00000000 - démarrer au bloc 0x0000000000000001 
 + 
 + 
 +0000005A ​ 0080              dw 0x8000 ​          ; Emplacement de l'​offset où le contenu du tampon sera copié 
 +0000005C ​ 01000000 ​         dd 0x00000001 ;​ Adresse LBA (valeur basse) où se trouve le secteur suivant de chargement (core.img) 
 +00000060 ​ 00000000 ​         dd 0x00000000 ;​ Valeur haute du qword de l'​adresse LBA 
 +00000064 ​ FF                db 0xff             ; 0xff pour le chargement de core.img sur le disque de boot, si 0x80 premier disque dur, si 0x81 deuxième... 
 + 
 +00000065 ​ FA                cli 
 +00000066 ​ 90                nop 
 +00000067 ​ 90                nop 
 +00000068 ​ F6C280 ​           test dl,0x80 ; teste le bit 7 de dl (si activé=disque dur) 
 +0000006B ​ 7502              jnz 0x6f ; si disque dur 
 +0000006D ​ B280              mov dl,0x80 ; marque le périphérique comme disque dur 
 +0000006F ​ EA747C0000 ​       jmp word 0x0:​0x7c74 ;​ saute à la ligne suivante (car mbr chargé en 0000:​7c00) 
 +00000074 ​ 31C0              xor ax,ax 
 +00000076 ​ 8ED8              mov ds,ax 
 +00000078 ​ 8ED0              mov ss,ax 
 +0000007A ​ BC0020 ​           mov sp,0x2000 ; la pile pointe sur 0000:2000 
 +0000007D ​ FB                sti 
 +0000007E ​ A0647C ​           mov al,​[0x7c64] ;​ examine le contenu de l'​adresse 7C64 (ici 0xff) 
 +00000081 ​ 3CFF              cmp al,0xff 
 +00000083 ​ 7402              jz 0x87 
 +00000085 ​ 88C2              mov dl,al ; si non égal à 0xff, sauvegardé dans dl - si core.img est sur un autre disque 
 +00000087 ​ 52                push dx 
 +00000088 ​ BB1704 ​           mov bx,​0x417 ​       ; adresse clavier 
 +0000008B ​ 802703 ​           and byte [bx],​0x3 ​  ; teste si une touche shift est activée 
 +0000008E ​ 7406              jz 0x96 
 +00000090 ​ BE887D ​           mov si,0x7d88 ; pointe sur la chaine "​GRUB"​ 
 +00000093 ​ E81C01 ​           call word 0x1b2 
 + 
 +00000096 ​ BE057C ​           mov si,0x7c05 ; définit une zone tampon pour les paramètres de chargement 
 +00000099 ​ F6C280 ​           test dl,0x80 ; teste si disque dur 
 +0000009C ​ 7448              jz 0xe6 ; pas disque dur 
 +0000009E ​ B441              mov ah,0x41 
 +000000A0 ​ BBAA55 ​           mov bx,0x55aa 
 +000000A3 ​ CD13              int 0x13 ; installation check 
 +000000A5 ​ 5A                pop dx 
 +000000A6 ​ 52                push dx 
 +000000A7 ​ 723D              jc 0xe6 ; extensions non supportées 
 +000000A9 ​ 81FB55AA ​         cmp bx,0xaa55 
 +000000AD ​ 7537              jnz 0xe6 ; extension non installée 
 + 
 +000000AF ​ 83E101 ​           and cx,byte +0x1 
 +000000B2 ​ 7432              jz 0xe6 ; fonctions 42h-44h, 47h et 48h non supportées 
 + 
 +; traitement extension lba_mode 
 +000000B4 ​ 31C0              xor ax,ax 
 +000000B6 ​ 894404 ​           mov [si+0x4],​ax ;​ met zéro en 7c09 et 7c0a 
 +000000B9 ​ 40                inc ax 
 +000000BA ​ 8844FF ​           mov [si-0x1],​al ;​ met 1 en 7c04 (1=lba_mode) 
 +000000BD ​ 894402 ​           mov [si+0x2],​ax ;​ met 0x0001 en 7c07 
 +000000C0 ​ C7041000 ​         mov word [si],0x10 ; met 0x0010 en 7c05 
 +000000C4 ​ 668B1E5C7C ​       mov ebx,​[0x7c5c] ​   ; récupère l'​emplacement (partie basse du qword) de core.img 
 +000000C9 ​ 66895C08 ​         mov [si+0x8],​ebx ​   ; sauvegarde cet emplacement pour le charger 
 +000000CD ​ 668B1E607C ​       mov ebx,​[0x7c60] ​   ; récupère la partie haute du qword de core.img 
 +000000D2 ​ 66895C0C ​         mov [si+0xc],​ebx ​   ; sauvegarde 
 +000000D6 ​ C744060070 ​       mov word [si+0x6],​0x7000 ​ ; adresse de segment du tampon 
 +000000DB ​ B442              mov ah,0x42 
 +000000DD ​ CD13              int 0x13 ; fonction extended read 
 +000000DF ​ 7205              jc 0xe6 ; si erreur 
 +000000E1 ​ BB0070 ​           mov bx,0x7000 
 +000000E4 ​ EB76              jmp short 0x15c 
 + 
 +; traitement sans extension chs_mode 
 +000000E6 ​ B408              mov ah,0x8 
 +000000E8 ​ CD13              int 0x13 ; récupère les paramètres du disque (numéro maxi tête, numéro maxi secteur, numéro maxi cylindre) 
 +000000EA ​ 730D              jnc 0xf9 ; si pas d'​erreur 
 +000000EC ​ F6C280 ​           test dl,0x80 
 +000000EF ​ 0F84D000 ​         jz word 0x1c3 
 +000000F3 ​ BE937D ​           mov si,0x7d93 ; pointe sur la chaine "Hard Disk"  
 +000000F6 ​ E98200 ​           jmp word 0x17b 
 + 
 +000000F9 ​ 660FB6C6 ​         movzx eax,dh ; numéro maxi de têtes 
 +000000FD ​ 8864FF ​           mov [si-0x1],​ah ;​ met zéro en 7c04 
 +00000100 ​ 40                inc ax ; nombre de têtes 
 +00000101 ​ 66894404 ​         mov [si+0x4],​eax ;​ sauvegardé en 7c09 
 +00000105 ​ 0FB6D1 ​           movzx dx,cl ; 2bits pour cylindre+nombre max de secteurs 
 +00000108 ​ C1E202 ​           shl dx,0x2 ; décale de 2 bits vers la gauche 
 +0000010B ​ 88E8              mov al,ch ; 8 bits de poids faible n° maxi cylindre 
 +0000010D ​ 88F4              mov ah,dh ; 2 bits de poids fort cylindre 
 +0000010F ​ 40                inc ax ; nb de cylindres 
 +00000110 ​ 894408 ​           mov [si+0x8],​ax ;​ sauvegardé en 7c0d 
 +00000113 ​ 0FB6C2 ​           movzx ax,dl ; copie le numéro maxi de secteurs (x4) 
 +00000116 ​ C0E802 ​           shr al,0x2 ; numéro maxi de secteurs=nb secteurs 
 +00000119 ​ 668904 ​           mov [si],eax ; sauvegardé 
 +0000011C ​ 66A1607C ​         mov eax,​[0x7c60] 
 +00000120 ​ 6609C0 ​           or eax,eax ; teste si zéro 
 +00000123 ​ 754E              jnz 0x173           ; erreur de géométrie 
 + 
 +; Convertit adresse linéaire en tête, secteur et cylindre 
 +00000125 ​ 66A15C7C ​         mov eax,​[0x7c5c] ​   ; charge l'​adresse LBA de l'​emplacement de core.img (valeur basse qword) 
 +00000129 ​ 6631D2 ​           xor edx,edx ; met à zéro 
 +0000012C ​ 66F734 ​           div dword [si] ; divise l'​adresse LBA par le nombre de secteurs par piste 
 +0000012F ​ 88D1              mov cl,dl ; reste de la division = numéro secteur (commencement à 0) 
 +00000131 ​ 31D2              xor dx,dx 
 +00000133 ​ 66F77404 ​         div dword [si+0x4] ; divise par le nombre de têtes - donne un nb de cylindres  
 +00000137 ​ 3B4408 ​           cmp ax,​[si+0x8] ​ ; compare au nombre de cylindres du disque 
 +0000013A ​ 7D37              jnl 0x173 ; supérieur au nombre de cylindres du disque - erreur 
 +0000013C ​ FEC1              inc cl ; rajoute 1 car les n°secteurs commencent à 1 
 +0000013E ​ 88C5              mov ch,al ; 8 bits de poids faible n°cylindre 
 +00000140 ​ 30C0              xor al,al 
 +00000142 ​ C1E802 ​           shr ax,0x2 ; décale de 2 bits à droite (les bits 6 et 7 pour poids fort cylindre) 
 +00000145 ​ 08C1              or cl,al ; modifie les bits 7 et 6 de cl en conséquence (poids fort cylindre) 
 +00000147 ​ 88D0              mov al,dl ; numéro de tête = reste division 
 +00000149 ​ 5A                pop dx 
 +0000014A ​ 88C6              mov dh,al ; numéro de tête 
 +0000014C ​ BB0070 ​           mov bx,0x7000 
 +0000014F ​ 8EC3              mov es,bx 
 +00000151 ​ 31DB              xor bx,bx ; tampon en 7000:0000 
 +00000153 ​ B80102 ​           mov ax,0x201 ; fonction ah=02h = lecture secteur, al=01 = 1 secteur 
 +00000156 ​ CD13              int 0x13 ; lit un secteur 
 +00000158 ​ 721E              jc 0x178 ; erreur de lecture 
 +0000015A ​ 8CC3              mov bx,es 
 + 
 +; Copie des données chargées (partie commune mode CHS ou LBA) 
 +0000015C ​ 60                pushaw 
 +0000015D ​ 1E                push ds 
 +0000015E ​ B90001 ​           mov cx,0x100 
 +00000161 ​ 8EDB              mov ds,bx ; charge le segment du buffer 
 +00000163 ​ 31F6              xor si,si ; ds:si pointe sur 7000:0000 
 +00000165 ​ BF0080 ​           mov di,0x8000 
 +00000168 ​ 8EC6              mov es,si ; es:di pointe sur 0000:8000 
 +0000016A ​ FC                cld 
 +0000016B ​ F3A5              rep movsw ; copie le contenu du buffer de 7000:​0000-7000:​01FF en 0000:​8000-0000:​81FF 
 +0000016D ​ 1F                pop ds 
 +0000016E ​ 61                popaw 
 +0000016F ​ FF265A7C ​         jmp word near [0x7c5a]; saute en 0000:8000 (car 7c5a contient 8000) - début de core.img 
 + 
 + 
 +00000173 ​ BE8E7D ​           mov si,0x7d8e ; pointe sur la chaine "​Geom"​ 
 +00000176 ​ EB03              jmp short 0x17b 
 +00000178 ​ BE9D7D ​           mov si,0x7d9d ; pointe sur la chaine "​Read"​ 
 +0000017B ​ E83400 ​           call word 0x1b2 
 +0000017E ​ BEA27D ​           mov si,0x7da2 ; pointe sur la chaine "​Error"​ 
 +00000181 ​ E82E00 ​           call word 0x1b2 
 +00000184 ​ CD18              int 0x18 
 +00000186 ​ EBFE              jmp short 0x186 ; boucle sans fin 
 + 
 +; Chaînes messages d'​erreur 
 +00000188 ​               db "GRUB ",0 
 +0000018E ​ db "​Geom",​0 
 +00000193 ​ db "Hard Disk",​0 
 +0000019D ​ db "​Read",​0 
 +000001A2 db " Error",​13,​10,​0 
 + 
 +; Affiche caractère 
 +000001AB ​ BB0100 ​           mov bx,0x1 
 +000001AE ​ B40E              mov ah,0xe 
 +000001B0 ​ CD10              int 0x10 ; affiche un caractère 
 + 
 +; Affiche une chaine 
 +000001B2 ​ AC                lodsb 
 +000001B3 ​ 3C00              cmp al,0x0 
 +000001B5 ​ 75F4              jnz 0x1ab ; teste la fin de la chaine 
 +000001B7 ​ C3                ret</​code>​ 
 +\\ 
 +<note tip>​L'​emplacement de la LBA où se trouve core.img est indiquée en 5c (8 octets). 
 +\\ 
 +Ici nous avons la LBA qui vaut 1, soit le secteur qui suit le mbr. Dans le cas d'un partitionnement GPT cet emplacement est occupé par l'​en-tête GPT et n'est plus disponible pour core.img. Il faudra donc mettre l'​adresse LBA de la partition bios_boot pour le boot en mode bios sur un disque GPT</​note>​ 
 +\\ 
 +Le programme chargé en mémoire à l'​adresse 0000:7c00 commence par l'​instruction jmp short 0x65 qui saute directement à l'​adresse 065 
 +\\ 
 +\\ 
 +Différentes parties sont visibles : 
 +\\ 
 +\\ 
 +de 065 à 095 - Routine vérifie que le boot s'​effectue à partir du disque dur 
 +\\ 
 +de 096 à 0b3 - Définit l'​emplacement des paramètres de chargement du prochain secteur et le mode CHS ou LBA selon les capacités du bios 
 +\\ 
 +de 0b4 à 0e5 - Charge le premier secteur de core.img en mode LBA (interruption bios int13/​ah=42h) 
 +\\ 
 +de 0e6 à 0f8 - Récupère les paramètres du disque et gère les erreurs 
 +\\ 
 +de 0f9 à 124 - Sauvegarde ces paramètres dans la zone des paramètres de chargement 
 +\\ 
 +de 125 à 15b - Convertit l'​adresse LBA de core.img dans le mode CHS et charge ce secteur dans le tampon (interruption bios int13/​ah=02h) 
 +\\ 
 +de 15c à 172 - Recopie le secteur chargé à son nouvel emplacement et saute à cet emplacement (première partie de core.img, soit diskboot.img) 
 +\\ 
 +de 173 à 187 - Affichage des messages d'​erreur 
 +\\ 
 +de 1ab à 1b0 - Affichage de caractères 
 +\\ 
 +de 1b2 à 1b7 - Affichage des chaînes des messages d'​erreurs 
 +\\
 ===== Voir aussi ===== ===== Voir aussi =====
 \\ \\
    
-  * **(fr)** [[http://​fr.wikipedia.org/​wiki/​Master_boot_record]] +  * **(fr)** [[https://​fr.wikipedia.org/​wiki/​Master_boot_record]] 
-  * **(fr)**[[http://​fr.wikipedia.org/​wiki/​Partition_de_disque_dur]] +  * **(fr)**[[https://​fr.wikipedia.org/​wiki/​Partition_de_disque_dur]] 
-  * [[http://​forum.ubuntu-fr.org/​viewtopic.php?​id=390336]] sur le forum ubuntu-fr +  * [[https://​forum.ubuntu-fr.org/​viewtopic.php?​id=390336]] sur le forum ubuntu-fr 
-  * **(fr)**[[http://​fr.wikipedia.org/​wiki/​Logical_block_addressing]]+  * **(fr)**[[https://​fr.wikipedia.org/​wiki/​Logical_block_addressing]]
  
  
  • la_partie_executable_du_mbr.1303301466.txt.gz
  • Dernière modification: Le 20/04/2011, 14:16
  • (modification externe)