Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
la_partie_executable_du_mbr [Le 21/04/2011, 17:17] Nasman |
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 BROUILLON}} | {{tag> tutoriel mbr BROUILLON}} | ||
Ligne 5: | Ligne 6: | ||
====== 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 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 ===== | ===== Exemple de zone exécutable d'un mbr ===== | ||
Ligne 60: | Ligne 62: | ||
J'ai effectué une analyse (partielle) du fonctionnement des différents morceaux mais des parties restent encore nébuleuses. | 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 et je me suis servi de la liste des [[http://www.ctyme.com/intr/int.htm|interruptions]] | + | 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. | établies par Ralph Brown. | ||
+ | \\ | ||
\\ | \\ | ||
Voilà donc à quoi ressemble la chose. | Voilà donc à quoi ressemble la chose. | ||
\\ | \\ | ||
- | <code>; Programme chargé en 0000:7C00 | + | <code>; Programme 16 bits chargé en 0000:7C00 |
00000000 EB63 jmp short 0x65 | 00000000 EB63 jmp short 0x65 | ||
00000002 90 nop | 00000002 90 nop | ||
00000003 D0 | 00000003 D0 | ||
+ | 00000004 resb 1 ; mode : 0x00 pour le mode CHS, 0x01 pour le mode LBA | ||
- | ; Buffer pour disque dur | + | ; Buffer pour chargement en mode CHS |
- | 00000004 resb 1 ; 0x00 | + | |
00000005 resd 1 ; nombre de secteurs | 00000005 resd 1 ; nombre de secteurs | ||
00000009 resd 1 ; nombre de têtes | 00000009 resd 1 ; nombre de têtes | ||
0000000D resd 1 ; nombre de cylindres | 0000000D resd 1 ; nombre de cylindres | ||
- | ; Buffer pour extension | + | ; Buffer pour chargement en mode LBA |
- | (00000004 resb 1 ; 0x01) | + | 00000005 resw 1 ; 0x0010 - taille paquet |
- | (00000005 resw 1 ; 0x0010 - taille paquet) | + | 00000007 resw 1 ; 0x0001 - nb blocs à transférer |
- | (00000007 resw 1 ; 0x0001 - nb block à transférer) | + | 00000009 resw 1 ; 0x0000 |
- | (00000009 resw 1 ; 0x0000) | + | 0000000B resw 1 ; 0x7000 - buffer en 0x70000000 |
- | (0000000B resw 1 ; 0x7000 - buffer en 0x70000000) | + | 0000000D resd 1 ; 0x00000001 - emplacement LBA du bloc à charger |
- | (0000000D resd 1 ; 0x00000001) | + | 00000011 resd 1 ; 0x00000000 - démarrer au bloc 0x0000000000000001 |
- | (00000011 resd 1 ; 0x00000000 - démarrer au bloc 0x0000000000000001) | + | |
- | + | ||
- | 00000004 BC007C mov sp,0x7c00 | + | |
- | 00000007 8EC0 mov es,ax | + | |
- | 00000009 8ED8 mov ds,ax | + | |
- | 0000000B BE007C mov si,0x7c00 | + | |
- | 0000000E BF0006 mov di,0x600 | + | |
- | 00000011 B90002 mov cx,0x200 | + | |
- | 00000014 FC cld | + | |
- | 00000015 F3A4 rep movsb ; copie le secteur de 7C00-7DFF en 600-7FF | + | |
- | 00000017 50 push ax | + | |
- | 00000018 681C06 push word 0x61c | + | |
- | 0000001B CB retf ; saute en 61c (contenu ci dessous) | + | |
- | 0000001C FB sti | ||
- | 0000001D B90400 mov cx,0x4 | ||
- | 00000020 BDBE07 mov bp,0x7be ; pointe sur le début de la table des partitions | ||
- | 00000023 807E0000 cmp byte [bp+0x0],0x0 | + | 0000005A 0080 dw 0x8000 ; Emplacement de l'offset où le contenu du tampon sera copié |
- | 00000027 7C0B jl 0x34 ; teste si marqueur "boot" | + | 0000005C 01000000 dd 0x00000001 ; Adresse LBA (valeur basse) où se trouve le secteur suivant de chargement (core.img) |
- | 00000029 0F851001 jnz word 0x13d ; ni boot ni zéro | + | 00000060 00000000 dd 0x00000000 ; Valeur haute du qword de l'adresse LBA |
- | 0000002D 83C510 add bp,byte +0x10 ; pointe sur partition suivante | + | 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... |
- | 00000030 E2F1 loop 0x23 ; 4 boucles pour 4 partitions | + | |
- | 00000032 CD18 int 0x18 ; appelé si pas de partition de boot | + | |
- | 00000034 885600 mov [bp+0x0],dl | + | |
- | 00000037 55 push bp ; sauvegarde adresse (partition de boot) | + | |
- | 00000038 C6461105 mov byte [bp+0x11],0x5 | + | |
- | 0000003C C6461000 mov byte [bp+0x10],0x0 | + | |
- | 00000040 B441 mov ah,0x41 | + | |
- | 00000042 BBAA55 mov bx,0x55aa | + | |
- | 00000045 CD13 int 0x13 ; installation check | + | |
- | 00000047 5D pop bp | + | |
- | 00000048 720F jc 0x59 ; extension non supportée | + | |
- | 0000004A 81FB55AA cmp bx,0xaa55 ; | + | |
- | 0000004E 7509 jnz 0x59 ; extension non installée | + | |
- | 00000050 F7C10100 test cx,0x1 | + | |
- | 00000054 7403 jz 0x59 ; fonctions 42h-44h, 47h et 48h non supportées | + | |
- | 00000056 FE4610 inc byte [bp+0x10] | + | |
- | 00000059 66 | + | |
- | 0000005A 0080 | + | |
- | 0000005C 01000000 dd 0x00000001 ; numéro secteur | + | |
- | 00000060 00000000 dd 0x00000000 ; | + | |
- | 00000064 FF db 0xff | + | |
00000065 FA cli | 00000065 FA cli | ||
Ligne 142: | Ligne 108: | ||
00000081 3CFF cmp al,0xff | 00000081 3CFF cmp al,0xff | ||
00000083 7402 jz 0x87 | 00000083 7402 jz 0x87 | ||
- | 00000085 88C2 mov dl,al ; si non égal à 0xff, sauvegardé dans dl | + | 00000085 88C2 mov dl,al ; si non égal à 0xff, sauvegardé dans dl - si core.img est sur un autre disque |
00000087 52 push dx | 00000087 52 push dx | ||
- | 00000088 BB1704 mov bx,0x417 | + | 00000088 BB1704 mov bx,0x417 ; adresse clavier |
- | 0000008B 802703 and byte [bx],0x3 | + | 0000008B 802703 and byte [bx],0x3 ; teste si une touche shift est activée |
0000008E 7406 jz 0x96 | 0000008E 7406 jz 0x96 | ||
00000090 BE887D mov si,0x7d88 ; pointe sur la chaine "GRUB" | 00000090 BE887D mov si,0x7d88 ; pointe sur la chaine "GRUB" | ||
00000093 E81C01 call word 0x1b2 | 00000093 E81C01 call word 0x1b2 | ||
- | 00000096 BE057C mov si,0x7c05 ; définit une zone tampon | + | 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 | 00000099 F6C280 test dl,0x80 ; teste si disque dur | ||
0000009C 7448 jz 0xe6 ; pas disque dur | 0000009C 7448 jz 0xe6 ; pas disque dur | ||
Ligne 162: | Ligne 128: | ||
000000AD 7537 jnz 0xe6 ; extension non installée | 000000AD 7537 jnz 0xe6 ; extension non installée | ||
- | ; traitement extension | ||
000000AF 83E101 and cx,byte +0x1 | 000000AF 83E101 and cx,byte +0x1 | ||
000000B2 7432 jz 0xe6 ; fonctions 42h-44h, 47h et 48h non supportées | 000000B2 7432 jz 0xe6 ; fonctions 42h-44h, 47h et 48h non supportées | ||
- | 000000B4 31C0 xor ax,ax | + | |
+ | ; traitement extension lba_mode | ||
+ | 000000B4 31C0 xor ax,ax | ||
000000B6 894404 mov [si+0x4],ax ; met zéro en 7c09 et 7c0a | 000000B6 894404 mov [si+0x4],ax ; met zéro en 7c09 et 7c0a | ||
000000B9 40 inc ax | 000000B9 40 inc ax | ||
- | 000000BA 8844FF mov [si-0x1],al ; met 1 en 7c04 | + | 000000BA 8844FF mov [si-0x1],al ; met 1 en 7c04 (1=lba_mode) |
- | 000000BD 894402 mov [si+0x2],ax ; met 0001 en 7c07 | + | 000000BD 894402 mov [si+0x2],ax ; met 0x0001 en 7c07 |
000000C0 C7041000 mov word [si],0x10 ; met 0x0010 en 7c05 | 000000C0 C7041000 mov word [si],0x10 ; met 0x0010 en 7c05 | ||
- | 000000C4 668B1E5C7C mov ebx,[0x7c5c] | + | 000000C4 668B1E5C7C mov ebx,[0x7c5c] ; récupère l'emplacement (partie basse du qword) de core.img |
- | 000000C9 66895C08 mov [si+0x8],ebx | + | 000000C9 66895C08 mov [si+0x8],ebx ; sauvegarde cet emplacement pour le charger |
- | 000000CD 668B1E607C mov ebx,[0x7c60] | + | 000000CD 668B1E607C mov ebx,[0x7c60] ; récupère la partie haute du qword de core.img |
- | 000000D2 66895C0C mov [si+0xc],ebx | + | 000000D2 66895C0C mov [si+0xc],ebx ; sauvegarde |
- | 000000D6 C744060070 mov word [si+0x6],0x7000 | + | 000000D6 C744060070 mov word [si+0x6],0x7000 ; adresse de segment du tampon |
000000DB B442 mov ah,0x42 | 000000DB B442 mov ah,0x42 | ||
000000DD CD13 int 0x13 ; fonction extended read | 000000DD CD13 int 0x13 ; fonction extended read | ||
Ligne 182: | Ligne 149: | ||
000000E4 EB76 jmp short 0x15c | 000000E4 EB76 jmp short 0x15c | ||
- | ; traitement sans extension | + | ; traitement sans extension chs_mode |
000000E6 B408 mov ah,0x8 | 000000E6 B408 mov ah,0x8 | ||
- | 000000E8 CD13 int 0x13 ; récupère les paramètres du disque | + | 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 | 000000EA 730D jnc 0xf9 ; si pas d'erreur | ||
000000EC F6C280 test dl,0x80 | 000000EC F6C280 test dl,0x80 | ||
Ligne 191: | Ligne 158: | ||
000000F6 E98200 jmp word 0x17b | 000000F6 E98200 jmp word 0x17b | ||
- | ; Disque dur OK | ||
000000F9 660FB6C6 movzx eax,dh ; numéro maxi de têtes | 000000F9 660FB6C6 movzx eax,dh ; numéro maxi de têtes | ||
000000FD 8864FF mov [si-0x1],ah ; met zéro en 7c04 | 000000FD 8864FF mov [si-0x1],ah ; met zéro en 7c04 | ||
Ligne 207: | Ligne 173: | ||
0000011C 66A1607C mov eax,[0x7c60] | 0000011C 66A1607C mov eax,[0x7c60] | ||
00000120 6609C0 or eax,eax ; teste si zéro | 00000120 6609C0 or eax,eax ; teste si zéro | ||
- | 00000123 754E jnz 0x173 | + | 00000123 754E jnz 0x173 ; erreur de géométrie |
; Convertit adresse linéaire en tête, secteur et cylindre | ; Convertit adresse linéaire en tête, secteur et cylindre | ||
- | 00000125 66A15C7C mov eax,[0x7c5c] | + | 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 | 00000129 6631D2 xor edx,edx ; met à zéro | ||
- | 0000012C 66F734 div dword [si] ; division numéro secteur/nb secteurs par piste | + | 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 | + | 0000012F 88D1 mov cl,dl ; reste de la division = numéro secteur (commencement à 0) |
00000131 31D2 xor dx,dx | 00000131 31D2 xor dx,dx | ||
00000133 66F77404 div dword [si+0x4] ; divise par le nombre de têtes - donne un nb de cylindres | 00000133 66F77404 div dword [si+0x4] ; divise par le nombre de têtes - donne un nb de cylindres | ||
- | 00000137 3B4408 cmp ax,[si+0x8] | + | 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 | 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 | 0000013C FEC1 inc cl ; rajoute 1 car les n°secteurs commencent à 1 | ||
Ligne 234: | Ligne 200: | ||
0000015A 8CC3 mov bx,es | 0000015A 8CC3 mov bx,es | ||
+ | ; Copie des données chargées (partie commune mode CHS ou LBA) | ||
0000015C 60 pushaw | 0000015C 60 pushaw | ||
0000015D 1E push ds | 0000015D 1E push ds | ||
0000015E B90001 mov cx,0x100 | 0000015E B90001 mov cx,0x100 | ||
00000161 8EDB mov ds,bx ; charge le segment du buffer | 00000161 8EDB mov ds,bx ; charge le segment du buffer | ||
- | 00000163 31F6 xor si,si ; ds:di pointe sur 7000:0000 | + | 00000163 31F6 xor si,si ; ds:si pointe sur 7000:0000 |
00000165 BF0080 mov di,0x8000 | 00000165 BF0080 mov di,0x8000 | ||
00000168 8EC6 mov es,si ; es:di pointe sur 0000:8000 | 00000168 8EC6 mov es,si ; es:di pointe sur 0000:8000 | ||
Ligne 245: | Ligne 212: | ||
0000016D 1F pop ds | 0000016D 1F pop ds | ||
0000016E 61 popaw | 0000016E 61 popaw | ||
- | 0000016F FF265A7C jmp word near [0x7c5a]; saute en 0000:8000 (car 7c5a contient 8000) | + | 0000016F FF265A7C jmp word near [0x7c5a]; saute en 0000:8000 (car 7c5a contient 8000) - début de core.img |
Ligne 257: | Ligne 224: | ||
00000186 EBFE jmp short 0x186 ; boucle sans fin | 00000186 EBFE jmp short 0x186 ; boucle sans fin | ||
- | ; Chaines messages d'erreur | + | ; Chaînes messages d'erreur |
00000188 db "GRUB ",0 | 00000188 db "GRUB ",0 | ||
0000018E db "Geom",0 | 0000018E db "Geom",0 | ||
Ligne 275: | Ligne 242: | ||
000001B7 C3 ret</code> | 000001B7 C3 ret</code> | ||
\\ | \\ | ||
- | La partie qui commence à l'adresse hexa 65 est commune avec le fichier boot.img qui se trouve dans /boot/grub/ | + | <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 : | ||
+ | \\ | ||
\\ | \\ | ||
- | Le programme chargé en mémoire à l'adresse 0000:7c00 commence par l'instruction jmp short 0x65 qui saute directement dans la partie commune à boot.img | + | 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 | ||
\\ | \\ | ||
- | Différentes parties sont visibles | + | de 0b4 à 0e5 - Charge le premier secteur de core.img en mode LBA (interruption bios int13/ah=42h) |
- | de 004 à 01b - Routine qui recopie à une autre adresse le contenu du mbr - peut être en prévision du chargement d'un autre secteur. | + | |
\\ | \\ | ||
- | de 01c à 037 - Détermine la partition de boot | + | de 0e6 à 0f8 - Récupère les paramètres du disque et gère les erreurs |
\\ | \\ | ||
- | de 038 à 059 - Détermine si le bios reconnait le système d'adressage LBA | + | de 0f9 à 124 - Sauvegarde ces paramètres dans la zone des paramètres de chargement |
\\ | \\ | ||
- | de 125 à 14a - Calcule les valeurs HSC à partir de la LBA | + | 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 14c à 158 - Charge un secteur | + | 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 à 186 - Gestion des erreurs | + | de 173 à 187 - Affichage des messages d'erreur |
\\ | \\ | ||
de 1ab à 1b0 - Affichage de caractères | de 1ab à 1b0 - Affichage de caractères | ||
\\ | \\ | ||
- | de 1b2 à 1b7 - Affichage des chaines des messages d'erreurs | + | 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]] |