Chapitre – 13
LECTURE ET MODIFICATION DU MBR PAR PROGRAMMATION
Enregistrement de démarrage DOS (DBR) / Secteur de démarrage DOS
Après la table de partition, le secteur de démarrage DOS (DBR), ou parfois appelé secteur de démarrage DOS, est la deuxième information la plus importante sur le disque dur.
Pour une discussion détaillée de DBR, voir le chapitre « Une approche logique des disques et des systèmes d'exploitation » abordé plus haut dans ce livre.
Le premier secteur logique de chaque partition DOS contiendra l'enregistrement de démarrage DOS (DBR) ou le secteur de démarrage DOS. Le travail de DBR est de charger le système d'exploitation du disque dur dans la mémoire principale de l'ordinateur et de transférer le contrôle du système au programme chargé.
Le DOS Boot Record (DBR) de la première partition d'un disque dur est généralement situé dans le secteur absolu 63 (le 64e secteur du disque) ou sous la forme CHS, c'est-à-dire que pour la plupart des disques, nous pouvons dire C–H–S = 0–1–1.
Cependant, cette disposition peut varier en fonction du SPT (secteurs par piste) du lecteur. Par exemple, sur un ancien disque dur de 245 Mo qui n’avait que 31 SPT, l’enregistrement de démarrage était situé dans le secteur 32 (secteur absolu 31).
Étant donné que la disquette ne comporte pas de partitions, elle ne possède pas de MBR ou de table de partition principale dans son premier secteur, mais contient un DBR dans le tout premier secteur.
Le DBR est créé par la commande FORMAT DOS après le partitionnement avec la commande FDISK. Le secteur où réside le DBR devient le secteur logique 1 de cette partition particulière pour DOS. Le numéro de secteur utilisé par DOS part du secteur physique où se trouve le DBR.
Le DBR contient un petit programme qui est exécuté par le programme exécutable Master Boot Record (MBR). Toutes les partitions DOS contiennent le code du programme permettant de démarrer la machine, c'est-à-dire. démarrer le système d'exploitation, mais seule cette partition reçoit le contrôle du Master Boot Record, qui est spécifié comme partition active dans l'entrée de la table de partition.
Si le DBR est endommagé de quelque façon que ce soit, le disque devrait être accessible si vous démarrez le système à partir d'une disquette ou d'un CD de démarrage. Bien que le disque dur ne soit pas bootable (si le DBR de la partition active est endommagé), cela ne devrait généralement pas affecter l'accès aux données sur le disque. Après avoir démarré le système à partir du disque de démarrage, vous pouvez accéder aux données.
/* Afficher les paramètres de démarrage de la disquette */
# inclure <dos.h>
# inclure <stdio.h>
basique( )
{
structure de chargement
{
code de caractère non signé[3] ; /* Code de transition */
unsigned char system_id[8] ;/* Nom et version OEM*/
int octets_par_seconde ; /* Octets par secteur */
symbole sec_per_clus ; /* Secteurs par cluster */
int res_sec ; /* Secteurs réservés */
char gras_copies ; /* Nombre de FAT */
int entrée_répertoire_racine ; /* Numéro racine
Entrées du répertoire */
int non signé no_sects ; /* Nombre de secteurs dans
Volume logique */
format_id de caractère non signé ; /* Octet descripteur de média
*/
int sec_per_fat ; /* Secteurs sur FAT */
int sec_per_trk ; /* Secteurs par piste */
int no_sides ; /* Nombre de têtes */
int no_sp_res_sect ; /* Nombre de cachés
Secteur */
caractère non signé rest_code[482] ; /* Reste du code */
} ;
structure de chargement b ;
symbole temp[4] ;
int val, lecteur ;
val = absread(0, 1, 0, &b) ; /* Utiliser pour une disquette*/
si ( valeur == -1 )
{
printf ( "Erreur de lecture du disque... secteur défectueux\n" ) ;
sortie (1);
}
clrscr( ) ;
printf("Identifiant système = %s\n",
b.identifiant_système ) ;
printf ( "Octets par secteur = %d\n",
b.octets_en_sec ) ;
printf ( "Secteurs par cluster = %d\n",
b.sec_par_classe);
printf ( "Secteurs réservés = %d\n",
b.res_sec ) ;
printf ( "copies FAT = %d\n",
b.fat_copies ) ;
printf ( "Entrées du répertoire racine = %d\n",
b.entrée_root_dir ) ;
printf ( "Nombre de secteurs sur le disque = %u\n",
b.no_sects ) ;
printf ( "Octet de descripteur de média = %X\n",
b.format_id ) ;
printf ( "Secteurs par FAT = %d\n",
b.sec_par_graisse ) ;
printf ( "Secteurs par piste = %d\n",
b.sec_per_trk ) ;
printf ( "Nombre de côtés = %d\n",
b.pas_de_côtés ) ;
printf ( "Nombre de secteurs réservés = %d\n",
b.no_sp_res_sect ) ;
retourner 0;
}
Si vous exécutez ce programme pour tester le DBR d'une disquette de 1,44 M, 3½ pouces comportant 70 pistes, deux faces, 18 secteurs par piste et 512 octets dans un secteur, la sortie du programme s'affichera de la manière suivante :
ID système = +1<*uIHC
Octets par secteur = 512
Secteurs par cluster = 1
Secteurs réservés = 1
Copies FAT = 2
Entrées du répertoire racine = 224
Nombre de secteurs sur le disque = 2880
Octet de descripteur de support = F0
Secteurs par FAT = 9
Secteurs par piste = 18
Nombre de côtés = 2
Nombre de secteurs réservés = 0
Lecture du DBR des grands volumes
Les volumes de partition dont la taille est supérieure à 32 Mo ont un format DBR différent de celui des volumes DBR inférieurs ou égaux à 32 Mo.
Il s'agit de fournir un support pour de grands volumes de disque (pour une description détaillée, reportez-vous au chapitre « Approche logique des disques et du système d'exploitation », abordé plus haut dans ce livre).
Le format de l'enregistrement de démarrage DOS d'un volume FAT32 a été indiqué dans le tableau suivant :

Le programme suivant permet de lire le DBR des grands volumes, dont la taille est supérieure à 32 Mo :
/* Programme pour afficher les paramètres de démarrage d'un grand volume de disque */
# inclure « dos.h »
# inclure « stdio.h »
void main()
{
structure de démarrage
{
code de caractère non signé[3] ; /* Code de saut */
unsigned char system_id[8] ; /* Nom OEM et version */
int bytes_per_sec ; /* Octets par secteur */
char sec_per_clus ; /* Secteurs par cluster*/
unsigned int res_sec ; /* Nombre de réservés
Secteurs */
char fat_copies ; /* Nombre de FAT */
unsigned int root_dir_entry ;/* Nombre de racines
Entrée du répertoire */
unsigned int no_sects ; /* Nombre de secteurs dans
Volume logique (si
Le volume est <= 32 Mo) */
unsigned char Media_id ; /* Octet de descripteur de média
*/
unsigned int sec_per_fat ; /* Secteur par FAT */
unsigned int sec_per_trk ; /* Secteurs par piste */
unsigned int no_sides ; /* Nombre de têtes */
unsigned long no_sp_res_sect ; /* Nombre de cachés
Secteurs */
unsigned long long_sec_num ; /* Nombre total de secteurs dans
Volume logique
(Taille >32 Mo) */
unsigned long num_sec_per_FAT; /* Secteurs par FAT */
unsigned int binary_flags; /* Drapeaux binaires */
unsigned char version_of_FAT1; /* Premier octet de FAT
Version */
unsigned char version_of_FAT2; /* Deuxième octet de FAT
Version */
unsigned long root_dir_start_cluster;
/* Répertoire racine
Cluster de démarrage
Nombre */
int non signé sec_num_du_fichier_sys;
/* Numéro de secteur de
Système de fichiers
Secteur de l'information
*/
int non signé sec_num_of_backup_boot_sec;
/* Numéro de secteur de
Sauvegarder le secteur de démarrage
*/
unsigned char reserved[12]; /* Réservé */
caractère non signé numéro_de_lecteur_logique ;
/* Lecteur physique
Nombre de logiques
Volume */
unsigned char unused_byte; /* Octet inutilisé */
caractère non signé hex_extd_boot_signature;
/* Démarrage étendu
Signature(29H) */
unsigned long binary_volume_ID;/* ID du volume binaire */
unsigned char volume_label[11];/* Libellé du volume */
unsigned char FAT_name[8]; /* Nom FAT */
unsigned char rest_code[420] ; /* Reste 420 octets de
Le DBR */
unsigned char magic_number[2]; /* Nombre magique */
} ;
structure de démarrage b ;
caractère temp[4] ;
int val, lecteur,i;
val = biosdisk( 2, 0x80, 1,0,1,1, &b ) ;
/* Pour le premier disque dur */
si ( val == -1 )
{
printf ( "Erreur de lecture du disque... secteur défectueux\n" ) ;
sortie ( 1 ) ;
}
clrscr( ) ;
printf ( " Code d'instruction de saut = ");
pour(i=0;i<=2;i++)
{
printf("%X",b.code[i]);
}
printf("(H)\n ");
printf ( "Nom et version OEM = %s\n ",
b.id_système ) ;
printf ( "Octets par secteur = %u\n ",
b.octets_par_sec ) ;
printf ( "Secteurs par cluster = %u\n ",
b.sec_per_clus );
printf ( "Secteurs réservés = %u\n ",
b.res_sec ) ;
printf ( "copies FAT = %d\n ",
b.fat_copies ) ;
printf ( "Entrées du répertoire racine = %u\n ",
b.entrée_root_dir ) ;
printf ( "Nombre de secteurs sur le disque = %u\n ",
b.no_sects ) ;
printf ( "Octet de descripteur de média = %X(H)\n",
b.Media_id ) ;
printf ( "Secteurs par FAT = %u\n ",
b.sec_par_graisse ) ;
printf ( "Secteurs par piste = %u\n ",
b.sec_per_trk ) ;
printf ( "Nombre de côtés = %u\n ",
b.pas_de_côtés ) ;
printf ( "Nombre de secteurs réservés (cachés) = %lu\n ",
b.no_sp_res_sect ) ;
printf ( "========== Pour les disques de grande taille (> 32 Mo) ========\n");
printf ( "Nombre de secteurs, (si le volume est > 32 Mo) = %lu\n ",
b.long_sec_num) ;
printf ( “Nombre de secteurs par FAT = %lu\n “,
b.num_sec_par_FAT );
printf ( "Répertoire racine du cluster de départ = %lu\n ",
b.root_dir_start_cluster);
printf ( "Secteur d'informations du système de fichiers = %u\n ",
b.sec_num_du_fichier_sys);
printf ( "Numéro de secteur du secteur de démarrage de sauvegarde = %u\n ",
b.sec_num_de_sauvegarde_démarrage_sec);
printf ( "Numéro de lecteur physique = %X(H)\n",
b.numéro_de_lecteur_logique);
printf ( "Signature de démarrage étendue = %X(H)\n",
b.hex_extd_boot_signature);
printf ( "ID de volume binaire 32 bits = ");
Décimal_en_binaire (b.binary_volume_ID,32);
printf ( " (B)\n ");
printf ( "Étiquette de volume = ");
pour(i=0;i<=10;i++)
{
printf ( "%c",b.volume_label[i]);
}
printf ( "\n nom FAT = ");
pour(i=0;i<=7;i++)
{
printf ( "%c",b.FAT_name[i]);
}
printf ( "\n ");
printf ( "Nombre magique = %X%X(H)",
b.numéro_magique[0],b.numéro_magique[1]);
obtenir();
}
//////// Fonction de conversion décimale en binaire \\\\\\\
Decimal_to_Binary (entrée longue non signée)
{
i non signé long;
int nombre = 0;
int binaire [32]; /* 32 bits MAX seulement 32
éléments au total */
faire
{
i = input%2; /* MOD 2 pour obtenir 1 ou 0*/
binary[count] = i; /* Charger les éléments dans le
Tableau binaire */
entrée = entrée/2 ; /* Divisez l'entrée par 2 pour
décrémenter via binaire */
count++; /* Compter combien d'éléments
sont nécessaires */
}while (entrée > 0);
/* Inverser et afficher des chiffres binaires */
faire
{
printf ("%d", binaire[compte - 1]);
compter--;
} tandis que (compte > 0);
retourner 0;
}
Lorsque le programme est exécuté pour lire le DBR d'un grand volume, la sortie du programme s'affiche comme suit :
Code d'instruction de saut = EB5890 (H)
Nom et version OEM = MSWIN4.1
Octets par secteur = 512
Secteurs par cluster = 8
Secteurs réservés = 32
Copies FAT = 2
Entrées du répertoire racine = 0
Nombre de secteurs sur le disque = 0
Octet de descripteur de support = F8 (H)
Secteurs par FAT = 0
Secteurs par piste = 63
Nombre de côtés = 255
Nombre de secteurs réservés (masqués) = 63
=========== Pour les disques de grande taille (> 32 Mo) =========== Nombre de secteurs (si le volume est > 32 Mo) = 11277567 Nombre de secteurs par FAT = 11003 Cluster de départ du répertoire racine = 2 Secteur d'informations sur le système de fichiers = 1 Numéro de secteur du secteur de démarrage de sauvegarde = 6 Numéro de lecteur physique = 80 (H) Signature de démarrage étendu = 29 (H) ID de volume binaire 32 bits = 110101010001100001110111100101 (B) Nom du volume = SAAYA Nom FAT = FAT32 Numéro magique = 55AA (H)
Dans la sortie du programme, nous voyons que les paramètres suivants sont affichés à zéro :
- Entrée du répertoire racine
- Nombre de secteurs sur le disque
- Nombre de secteurs par FAT
Ces paramètres sont ainsi parce que ces valeurs sont définies sur zéro, si le volume de partition est supérieur à 32 Mo et que les informations réelles se trouvent dans le bloc d'informations de volume étendu du DBR.
Par exemple, dans la partie initiale des informations DBR, le nombre de secteurs par FAT est de 0 et dans le bloc d'informations de volume étendu de DBR, le nombre de secteurs par FAT est de 11 003, ce qui correspond à la valeur réelle de ce grand volume.
Le DBR du volume contient des informations importantes sur les paramètres du disque, qui peuvent être utilisées pour lier toutes les informations de données à des fins de programmation. Par exemple, si vous souhaitez accéder aux DBR d'autres volumes de partition sur le disque, vous pouvez les calculer en fonction du nombre de secteurs, écrits dans le DBR et d'autres informations connexes.
Si vous souhaitez accéder à l'approche Disque avec cluster, vous pouvez effectuer des calculs à l'aide de Secteurs par cluster, secteurs par FAT et d'autres informations.
Si vous utilisez un disque dur d'une capacité supérieure à 8,4 Go (voir le chapitre « Approche logique des disques et du système d'exploitation », abordé plus haut dans ce livre), utilisez des extensions pour accéder à tous les DBR du disque au-delà de 8,4 Go. Reportez-vous aux fonctions de lecture-écriture étendues, données dans les chapitres précédents
Comment récupérer le DBR avec la programmation
Vous pouvez récupérer le DBR du volume de disque jusqu'à 100 % en utilisant une approche astucieuse et des calculs logiques. Comme nous l'avons évoqué au sujet des approches logiques des systèmes de fichiers dans le chapitre « Approche logique des disques et des systèmes d'exploitation », plus haut dans ce livre, chaque information dans le DBR est écrite dans le cadre d'une limite ou d'une règle.
Chaque paramètre écrit dans le DBR a une signification spécifique et est écrit ainsi en suivant une règle et une raison spécifiques. C'est pourquoi les informations du DBR, si elles sont perdues, peuvent être reliées ou réécrites manuellement si vous suivez ces règles et utilisez votre esprit rusé pour découvrir quoi et comment y remédier.
Par exemple, le tableau ci-dessous décrit le nombre de secteurs par cluster pour différents systèmes de fichiers, à l'aide duquel vous pouvez trouver le nombre de secteurs par cluster pour votre disque. Supposons que vous disposiez d'un volume d'environ 10 Go sur votre disque et que le système d'exploitation que vous utilisiez était Windows 98.
Maintenant, si les informations « Secteurs par cluster » du DBR du volume sont corrompues, essayons de savoir quel système de fichiers et combien de secteurs par cluster vous aviez dans le volume de votre disque.
Comme le système d'exploitation de votre disque était Windows 98, qui ne prend en charge que le système de fichiers FAT, le système de fichiers de votre volume était donc FAT. Pensons maintenant à la taille du volume, qui était d'environ 10 Go.
Nous savons que la partition de 10 Go n'est pas prise en charge par FAT16 (voir le tableau ci-dessous), par conséquent le système de fichiers du volume doit être FAT32.
Essayons maintenant de calculer le nombre de secteurs par cluster pour le volume. Comme nous le voyons dans le tableau, la partition comprise entre 8 Go et 16 Go possède un cluster de 8 secteurs.

Nous pouvons donc maintenant conclure que dans le volume, le système de fichiers était FAT32 avec 8 secteurs par cluster. De même, nous pouvons assembler les autres informations du DBR en utilisant d'autres approches logiques décrites dans les chapitres précédents de ce livre.
Le programme suivant a été écrit pour réécrire les informations des paramètres du disque en DBR de 1,44 Mo, disquette 3½ pouces, avec 80 pistes, 2 têtes (côtés) et 18 secteurs par piste.
/* Programme pour réécrire les paramètres d'une disquette de 1,44 Mo, 3½ pouces, vers son DBR */
# inclure « dos.h »
# inclure « stdio.h »
structure de démarrage
{
code de caractère non signé[3] ; /* Code de saut */
unsigned char system_id[8] ; /* ID et version OEM*/
int bytes_per_sec ; /* Octets par secteur */
char sec_per_clus ; /* Nombre de secteurs
Par cluster */
int res_sec ; /* Secteurs réservés */
char fat_copies ; /* Nombre de FAT */
int root_dir_entry ; /* Nombre de racines
Entrées du répertoire */
unsigned int no_sects ; /* Nombre total
Secteurs */
unsigned char format_id ; /* Descripteur de média
Octet */
int sec_per_fat ; /* Secteurs par FAT */
int sec_per_trk ; /* Secteurs par FAT */
int no_sides ; /* Nombre de
Côtés (têtes) */
int no_sp_res_sect ; /* Nombre de cachés
Secteurs */
unsigned char rest_code[482] ;/* Reste du code de 482 octets
de DBR */
} ;
structure de démarrage b ;
principal( )
{
avec un indice;
val = absread(0, 1, 0, &b); /* Utiliser pour une disquette */
si ( val == -1 )
{
printf ( "\n Erreur de lecture du disque... secteur défectueux\n" ) ;
sortie ( 1 ) ;
}
clrscr( ) ;
affichage_info();
obtenir();
printf("\n Récupération en cours du BDR de la disquette.....\n");
Récupérer_avec_des_valeurs();
printf ( "\n Disque récupéré avec succès." ) ;
affichage_info();
retourner 0;
}
/* Fonction pour modifier les paramètres de DBR */
Récupérer_avec_des_valeurs()
{
int valeur = 0;
/* Code de saut de 3 octets pour disquette */
b.code[0] = 0xEB;
b.code[1]= 0x3E;
b.code[2]= 0x90 ;
/* ID système de 8 octets */
strcpy(b.system_id, "+05PSIHC");
/* Octets par secteur = 512 */
b.octets_par_sec = 512;
/* Secteur par cluster pour disquette 3,5" de 1,44 M = 1 */
b.sec_per_clus = 1;
/* Nombre de secteurs réservés = 1 */
b.res_sec =1;
/* Nombre de copies FAT = 2 */
b.fat_copies =2;
/* Nombre d'entrées du répertoire racine = 224 */
b.root_dir_entry = 224;
/* Nombre de secteurs sur le disque = 2880 */
b.no_sects = 2880;
/* Octet descripteur de média pour disquette = F0 (H) */
b.format_id = 0xF0;
/* Secteurs par FAT = 9 */
b.sec_per_fat = 9;
/* Secteurs par piste = 18 */
b.sec_per_trk = 18;
/* Nombre de côtés = 2 */
b.no_sides =2;
/* Nombre de secteurs réservés spéciaux (ou cachés)
Secteurs) = 0 */
b.no_sp_res_sect = 0;
/* Utiliser pour une disquette*/
val = abswrite ( 0, 1, 0, &b ) ;
si ( val == -1 )
{
printf ( "\n Erreur d'écriture sur le disque... secteur défectueux\n" ) ;
printf ( " Le disque n'a pas été récupéré. " ) ;
sortie ( 1 ) ;
}
retourner 0;
}
afficher_info()
{
printf ( "\n Code de saut (Hex) = %X%X%X (H)\n",
b.code[0],b.code[1],b.code[2]);
printf ( " ID système = %s\n",
b.id_système ) ;
printf ( " Octets par secteur = %d\n",
b.octets_par_sec ) ;
printf ( " Secteurs par cluster = %d\n",
b.sec_per_clus );
printf ( " Secteurs réservés = %d\n",
b.res_sec ) ;
printf ( " Copies FAT = %d\n",
b.fat_copies ) ;
printf ( " Entrées du répertoire racine = %d\n",
b.entrée_root_dir ) ;
printf ( " Nombre de secteurs sur le disque = %u\n",
b.no_sects ) ;
printf("Octet descripteur de média = %X\n",
b.format_id ) ;
printf("Secteurs sur FAT = %d\n",
b.sec_par_graisse ) ;
printf("Secteurs par piste = %d\n",
b.sec_per_trk ) ;
printf("Nombre de côtés = %d\n",
b.pas_de_côtés) ;
printf("Nombre de secteurs réservés = %d\n",
б.no_sp_res_sect ) ;
retourner 0;
}
Commentaires sur le codage :
La structure de démarrage est utilisée pour accéder au DBR, pour lire et écrire les paramètres du disque. La fonction display_info() affiche divers paramètres de disque en lisant le DBR. La fonction Recover_with_values() est utilisée pour modifier et restaurer les paramètres de la disquette DBR.
Les valeurs utilisées par la fonction Recover_with_values() sont pour une disquette DBR de 1,44 Mo et 3 ½ pouces. Une description de ces valeurs est donnée dans le tableau ci-dessous :
