Kapitel – 13
MBR MIT PROGRAMMIERUNG LESEN UND ÄNDERN
DOS-Bootdatensatz (DBR) / DOS-Bootsektor
Nach der Partitionstabelle ist der DOS-Bootdatensatz (DBR), manchmal auch DOS-Bootsektor genannt, die zweitwichtigste Information auf der Festplatte.
Eine ausführliche Erläuterung von DBR finden Sie im Kapitel „Ein logischer Ansatz für Festplatten und Betriebssysteme“, das weiter oben in diesem Buch besprochen wurde.
Der erste logische Sektor jeder DOS-Partition enthält den DOS Boot Record (DBR) oder DOS-Bootsektor. Die Aufgabe von DBR besteht darin, das Betriebssystem von der Festplatte in den Hauptspeicher des Computers zu laden und die Kontrolle über das System an das geladene Programm zu übertragen.
Der DOS-Boot-Record (DBR) für die erste Partition auf einer Festplatte befindet sich normalerweise im absoluten Sektor 63 (dem 64. Sektor auf der Festplatte) oder im CHS-Format, d. h. für die meisten Festplatten können wir sagen, C–H–S = 0–1–1.
Diese Anordnung kann jedoch je nach SPT (Sektoren pro Spur) des Laufwerks variieren. Beispielsweise befand sich auf einem alten 245-MB-Laufwerk, das nur 31 SPTs hatte, der Boot-Datensatz im Sektor 32 (absoluter Sektor 31).
Da die Diskette keine Partitionen hat, verfügt sie in ihrem ersten Sektor nicht über eine MBR oder Master Partition Table, sondern enthält im allerersten Sektor einen DBR.
Der DBR wird durch den DOS-Befehl FORMAT erstellt, nachdem die Partitionierung mit dem Befehl FDISK erfolgt ist. Der Sektor, in dem sich der DBR befindet, wird für DOS zum logischen Sektor 1 dieser bestimmten Partition. Die von DOS verwendete Sektornummer beginnt mit dem physischen Sektor, in dem sich der DBR befindet.
Der DBR enthält ein kleines Programm, das vom ausführbaren Programm Master Boot Record (MBR) ausgeführt wird. Alle DOS-Partitionen enthalten den Programmcode zum Booten der Maschine, d. h. Booten Sie das Betriebssystem, aber nur diese Partition erhält die Kontrolle vom Master Boot Record, der im Partitionstabelleneintrag als aktive Partition angegeben ist.
Wenn der DBR in irgendeiner Weise beschädigt ist, sollte auf die Festplatte zugegriffen werden können, wenn Sie das System von einer Startdiskette oder -CD starten. Obwohl die Festplatte nicht bootfähig ist (wenn der DBR der aktiven Partition beschädigt ist), sollte dies im Allgemeinen keinen Einfluss auf den Zugriff auf die Daten auf der Festplatte haben. Nach dem Booten des Systems von der Bootdiskette können Sie auf die Daten zugreifen.
/* Boot-Parameter der Diskette anzeigen */
# include <dos.h>
# include <stdio.h>
grundlegend( )
{
Ladestruktur
{
vorzeichenloser Zeichencode[3] ; /* Übergangscode */
unsigned char system_id[8] ;/* OEM-Name und Version*/
int Bytes_pro_Sek.; /* Bytes pro Sektor */
Symbol sec_per_clus; /* Sektoren pro Cluster */
int res_sec; /* Reservierte Sektoren */
verkohlte Fettkopien; /* Anzahl der FAT */
int root_dir_entry; /* Stammnummer
Verzeichniseinträge */
vorzeichenlose int no_sects; /* Anzahl der Sektoren in
Logisches Volumen */
vorzeichenloses Zeichenformat_ID; /* Mediendeskriptor-Byte
*/
int Sek. pro Fett; /* Sektoren auf FAT */
int Sek. pro Strecke; /* Sektoren pro Spur */
int keine_Seiten; /* Anzahl der Köpfe */
int keine_Sp_Resekte; /* Anzahl der versteckten
Sektor */
unsigned char rest_code[482] ; /* Rest des Codes */
} ;
Ladestruktur b;
Symbol temp[4] ;
int val, Laufwerk;
Wert = absread(0, 1, 0, &b); /* Für Diskette verwenden*/
wenn (Wert == -1)
{
printf ( "Fehler beim Lesen der Festplatte... fehlerhafter Sektor\n" ) ;
Ausgabe (1);
}
clrscr( );
printf("Systemkennung = %s\n",
b.systemkennung ) ;
printf ("Bytes pro Sektor = %d\n",
b.Bytes_in_Sek.) ;
printf ("Sektoren pro Cluster = %d\n",
b.sec_pro_Klasse);
printf ("Reservierte Sektoren = %d\n",
b.res_sec ) ;
printf ("FAT-Kopien = %d\n",
b.Fettkopien ) ;
printf ("Stammverzeichniseinträge = %d\n",
b.root_dir_entry ) ;
printf ("Anzahl der Sektoren auf der Festplatte = %u\n",
b.keine_sekten ) ;
printf ("Mediendeskriptor-Byte = %X\n",
b.format_id ) ;
printf ("Sektoren pro FAT = %d\n",
b.sec_per_fat ) ;
printf ("Sektoren pro Spur = %d\n",
b.sec_per_trk ) ;
printf ("Anzahl der Seiten = %d\n",
b.keine_seiten ) ;
printf ("Anzahl der reservierten Sektoren = %d\n",
b.no_sp_res_sect) ;
gebe 0 zurück;
}
Wenn Sie dieses Programm ausführen, um den DBR einer 1,44 MB großen, 3½ Zoll großen Diskette mit 70 Spuren, zwei Seiten, 18 Sektoren pro Spur und 512 Bytes in einem Sektor zu testen, wird die Ausgabe des Programms ungefähr wie folgt angezeigt:
System-ID = +1<*uIHC
Bytes pro Sektor = 512
Sektoren pro Cluster = 1
Reservierte Sektoren = 1
FAT-Kopien = 2
Stammverzeichniseinträge = 224
Anzahl der Sektoren auf der Festplatte = 2880
Mediendeskriptor-Byte = F0
Sektoren pro FAT = 9
Sektoren pro Spur = 18
Anzahl der Seiten = 2
Anzahl der reservierten Sektoren = 0
Lesen des DBR großer Datenmengen
Die Partitionsvolumes mit einer Größe von über 32 MB haben ein anderes DBR-Format als das DBR für Volumes mit weniger als oder gleich 32 MB.
Dies dient dazu, die Unterstützung großer Festplattenvolumina zu gewährleisten (eine ausführliche Beschreibung hierzu finden Sie im Kapitel „Logischer Ansatz für Festplatten und Betriebssysteme“, das weiter oben in diesem Buch besprochen wird).
Das Format des DOS-Boot-Records eines FAT32-Volumes ist in der folgenden Tabelle angegeben:

Das folgende Programm dient zum Lesen des DBR von großen Volumes, die größer als 32 MB sind:
/* Programm zum Anzeigen der Startparameter eines großen Datenträgers */
# "dos.h" einbinden
# include "stdio.h"
void main()
{
Strukturboot
{
unsigned char code[3] ; /* Sprungcode */
unsigned char system_id[8] ; /* OEM-Name & Version */
int bytes_per_sec; /* Bytes pro Sektor */
Zeichen Sek. pro Cluster; /* Sektoren pro Cluster*/
unsigned int res_sec ; /* Anzahl der reservierten
Sektoren */
char fat_copies; /* Anzahl der FATs */
unsigned int root_dir_entry ;/* Nummer des Root
Verzeichniseintrag */
unsigned int no_sects ; /* Anzahl der Sektoren in
Logisches Volume (falls
Volumen ist <= 32 MB) */
unsigned char Media_id ; /* Mediendeskriptor-Byte
*/
unsigned int sec_per_fat ; /* Sektor pro FAT */
unsigned int sec_per_trk; /* Sektoren pro Spur */
unsigned int no_sides; /* Anzahl der Köpfe */
unsigned long no_sp_res_sect ; /* Anzahl der versteckten
Sektoren */
unsigned long long_sec_num ; /* Gesamtzahl der Sektoren in
Logisches Volumen
(Größe >32 MB) */
unsigned long num_sec_per_FAT; /* Sektoren pro FAT */
unsigned int binary_flags; /* Binäre Flags */
unsigned char version_of_FAT1; /* Erstes Byte von FAT
Version */
unsigned char version_of_FAT2; /* Zweites Byte von FAT
Version */
vorzeichenloser langer Root-Dir-Start-Cluster;
/* Stammverzeichnis
Cluster wird gestartet
Nummer */
vorzeichenlose int Sek.-Nummer_des_Dateisystems;
/* Sektornummer von
Dateisystem
Informationssektor
*/
vorzeichenlose Ganzzahl Sek.-Anzahl_der_Backup-Boot-Sek.;
/* Sektornummer von
Bootsektor sichern
*/
unsigned char reserved[12]; /* Reserviert */
unsigned char logische Laufwerksnummer;
/* Physisches Laufwerk
Anzahl der logischen
Volumen */
unsigned char unused_byte; /* Unbenutztes Byte */
vorzeichenloses Zeichen hex_extd_boot_signature;
/* Erweiterter Bootvorgang
Signatur(29H) */
unsigned long binary_volume_ID;/* Binäre Volume-ID */
unsigned char volume_label[11];/* Datenträgerbezeichnung */
unsigned char FAT_name[8]; /* FAT-Name */
unsigned char rest_code[420] ; /* Restliche 420 Bytes von
Der DBR */
unsigned char magic_number[2]; /* Magische Zahl */
} ;
Struktur boot b;
Zeichentemperatur[4];
int val, Laufwerk, i;
Wert = Biosdisk(2, 0x80, 1,0,1,1, &b);
/* Für die erste Festplatte */
wenn (Wert == -1)
{
printf ( "Fehler beim Lesen der Festplatte... fehlerhafter Sektor\n" ) ;
Ausgang ( 1 ) ;
}
clrscr( );
printf ( " Sprunganweisungscode = ");
für (i = 0; i <= 2; i++)
{
printf("%X",b.code[i]);
}
printf("(H)\n ");
printf ( "OEM-Name und Version = %s\n ",
b.system_id ) ;
printf ("Bytes pro Sektor = %u\n",
b.Bytes_pro_Sek.) ;
printf ("Sektoren pro Cluster = %u\n",
b.sec_per_clus );
printf ("Reservierte Sektoren = %u\n",
b.res_sec ) ;
printf ( "FAT-Kopien = %d\n ",
b.Fettkopien ) ;
printf ( "Stammverzeichniseinträge = %u\n ",
b.root_dir_entry ) ;
printf ( "Anzahl der Sektoren auf der Festplatte = %u\n ",
b.keine_sekten ) ;
printf ( "Mediendeskriptor-Byte = %X(H)\n",
b.Medien-ID ) ;
printf ("Sektoren pro FAT = %u\n",
b.sec_per_fat ) ;
printf ("Sektoren pro Spur = %u\n",
b.sec_per_trk ) ;
printf ( "Anzahl der Seiten = %u\n ",
b.keine_seiten ) ;
printf ( "Anzahl der reservierten (versteckten) Sektoren= %lu\n ",
b.no_sp_res_sect) ;
printf ( "========== Für große (> 32 MB) Festplatten =========\n");
printf ( "Anzahl der Sektoren, (wenn das Volumen >32 MB ist) = %lu\n ",
b.lange_Sek._Anzahl);
printf ( „Anzahl der Sektoren pro FAT = %lu\n “,
b.Anzahl_Sekunden_pro_FAT);
printf ( "Stammverzeichnis Startcluster = %lu\n ",
b.root_dir_start_cluster);
printf ( "Dateisysteminformationen Sektor = %u\n ",
b.sec_num_of_file_sys);
printf ( "Sektornummer des Backup-Bootsektors = %u\n ",
b.sec_Anzahl_der_Backup-Boot-Sek.);
printf ( "Physische Laufwerksnummer = %X(H)\n",
b.logische_Laufwerksnummer);
printf ("Erweiterte Boot-Signatur = %X(H)\n",
b.hex_extd_boot_signature);
printf ( "32-Bit-Binär-Volume-ID = ");
Dezimal_zu_Binär (b.binary_volume_ID,32);
printf ( " (B)\n ");
printf ( "Datenträgerbezeichnung = ");
für (i = 0; i <= 10; i++)
{
printf ( "%c",b.Volume_Label[i]);
}
printf ( "\n FAT-Name = ");
für (i = 0; i <= 7; i++)
{
printf ( "%c",b.FAT_name[i]);
}
printf ( "\n ");
printf ("Magische Zahl = %X%X(H)",
b.magische_zahl[0],b.magische_zahl[1]);
getch();
}
//////// Konvertierungsfunktion von Dezimal zu Binär \\\\\\\\\
Dezimal_zu_Binär (lange Eingabe ohne Vorzeichen)
{
vorzeichenloses langes i;
int-Anzahl = 0;
int binary [32]; /* 32 Bit MAX nur 32
Elemente insgesamt */
Tun
{
i = input%2; /* MOD 2 um 1 oder 0 zu erhalten*/
binary[count] = i; /* Elemente in die
Binäres Array */
input = input/2; /* Dividiere input durch 2 zu
Dekrement über Binärzahl */
count++; /* Howy-Elemente zählen
werden benötigt */
}während (Eingabe > 0);
/* Binärziffern umkehren und ausgeben */
Tun
{
printf ("%d", binär[Anzahl - 1]);
zählen--;
} während (Anzahl > 0);
gebe 0 zurück;
}
Wenn das Programm zum Lesen des DBR eines großen Datenträgers ausgeführt wird, wird die Ausgabe des Programms wie folgt angezeigt:
Sprungbefehlscode = EB5890 (H)
OEM-Name und -Version = MSWIN4.1
Bytes pro Sektor = 512
Sektoren pro Cluster = 8
Reservierte Sektoren = 32
FAT-Kopien = 2
Stammverzeichniseinträge = 0
Anzahl der Sektoren auf der Festplatte = 0
Mediendeskriptor-Byte = F8 (H)
Sektoren pro FAT = 0
Sektoren pro Spur = 63
Anzahl der Seiten = 255
Anzahl der reservierten (versteckten) Sektoren = 63
=========== Für große Festplatten (> 32 MB) =========== Anzahl der Sektoren (wenn das Volumen > 32 MB ist) = 11277567 Anzahl der Sektoren pro FAT = 11003 Startcluster des Stammverzeichnisses = 2 Sektor mit Dateisysteminformationen = 1 Sektor Anzahl der Backup-Bootsektoren = 6 Nummer des physischen Laufwerks = 80 (H) Erweiterte Boot-Signatur = 29 (H) 32-Bit-Binär Datenträger-ID = 110101010001100001110111100101 (B) Datenträgerbezeichnung = SAAYA FAT-Name = FAT32 Magic Number = 55AA (H)
In der Ausgabe des Programms sehen wir, dass die folgenden Parameter als Null angezeigt werden:
- Stammverzeichniseintrag
- Anzahl der Sektoren auf der Festplatte
- Anzahl Sektoren pro FAT
Diese Parameter sind so, weil diese Werte auf Null gesetzt werden, wenn das Partitionsvolumen größer als 32 MB ist und die tatsächlichen Informationen im erweiterten Volumeninformationsblock des DBR zu finden sind.
Beispielsweise beträgt die Anzahl der Sektoren pro FAT im Anfangsteil der DBR-Informationen 0 und im erweiterten Volume-Informationsblock von DBR beträgt die Anzahl der Sektoren pro FAT 11003, was dem tatsächlichen Wert für dieses große Volume entspricht.
Der DBR des Volumes enthält wichtige Informationen zu den Festplattenparametern, die zum Verknüpfen aller Dateninformationen zu Programmierzwecken verwendet werden können. Wenn Sie beispielsweise auf die DBRs anderer Partitionsvolumes auf der Festplatte zugreifen möchten, können Sie diese anhand der Anzahl der in den DBR geschriebenen Sektoren und anderer zugehöriger Informationen berechnen.
Wenn Sie auf die Festplatte mit Cluster-Ansatz zugreifen möchten, können Sie Berechnungen mithilfe von Sektoren pro Cluster, Sektoren pro FAT und anderen Informationen durchführen.
Wenn Sie eine Festplatte mit mehr als 8,4 GB verwenden (siehe das Kapitel „Logischer Ansatz für Festplatten und Betriebssysteme“, das weiter oben in diesem Buch besprochen wurde), verwenden Sie Erweiterungen, um auf alle DBRs der Festplatte über 8,4 GB hinaus zuzugreifen. Weitere Informationen finden Sie in den erweiterten Lese-/Schreibfunktionen in den vorherigen Kapiteln.
So stellen Sie DBR mit Programmierung wieder her
Sie können den DBR des Datenträgervolumens mithilfe einiger raffinierter Ansätze und logischer Berechnungen bis zu 100 Prozent wiederherstellen. Wie wir bereits im Kapitel „Logischer Ansatz für Datenträger und Betriebssysteme“ in diesem Buch über logische Ansätze für Dateisysteme gesprochen haben, werden alle Informationen im DBR innerhalb bestimmter Grenzen oder Regeln geschrieben.
Jeder im DBR geschriebene Parameter hat eine bestimmte Bedeutung und wird nach bestimmten Regeln und aus bestimmten Gründen geschrieben. Deshalb können die Informationen im DBR bei Verlust manuell neu verknüpft oder neu geschrieben werden, wenn Sie diese Regeln befolgen und Ihren Verstand einsetzen, um herauszufinden, was und wie Sie das Problem beheben können.
Beispielsweise beschreibt die folgende Tabelle die Anzahl der Sektoren pro Cluster für verschiedene Dateisysteme. Mithilfe dieser Tabelle können Sie die Anzahl der Sektoren pro Cluster für Ihre Festplatte ermitteln. Nehmen wir an, Ihre Festplatte hat ein Volumen von ungefähr 10 GB und Sie verwenden Windows 98 als Betriebssystem.
Nun, wenn die „Sektoren pro Cluster“-Information des DBR des Datenträgers irgendwie beschädigt ist. Versuchen wir herauszufinden, welches Dateisystem und wie viele Sektoren pro Cluster Sie im Datenträger Ihrer Festplatte hatten.
Da das Betriebssystem auf Ihrer Festplatte Windows 98 war, das nur das FAT-Dateisystem unterstützt, war das Dateisystem Ihres Datenträgers FAT. Betrachten wir nun die Größe des Datenträgers, die ungefähr 10 GB betrug.
Wir wissen, dass die 10-GB-Partition nicht von FAT16 unterstützt wird (siehe folgende Tabelle), daher sollte das Dateisystem des Datenträgers FAT32 sein.
Versuchen wir nun, die Anzahl der Sektoren pro Cluster für das Volume zu berechnen. Wie wir in der Tabelle sehen, hat die Partition im Bereich von 8 GB bis 16 GB einen Cluster mit 8 Sektoren.

Daher können wir nun schlussfolgern, dass das Dateisystem im Datenträger FAT32 mit 8 Sektoren pro Cluster war. In ähnlicher Weise können wir die anderen Informationen des DBR mithilfe anderer logischer Ansätze zusammenstellen, die in den vorherigen Kapiteln dieses Buches beschrieben wurden.
Das folgende Programm wurde geschrieben, um die Informationen der Festplattenparameter im DBR einer 1,44 MB großen, 3½-Zoll-Diskette mit 80 Spuren, 2 Köpfen (Seiten) und 18 Sektoren pro Spur neu zu schreiben.
/* Programm zum Umschreiben der Parameter einer 1,44 MB großen, 3½ Zoll großen Diskette in ihren DBR */
# "dos.h" einbinden
# include "stdio.h"
Strukturboot
{
unsigned char code[3] ; /* Sprungcode */
unsigned char system_id[8] ; /* OEM ID und Version*/
int bytes_per_sec; /* Bytes pro Sektor */
char sec_per_clus; /* Anzahl der Sektoren
Pro Cluster */
int res_sec; /* Reservierte Sektoren */
char fat_copies; /* Anzahl der FATs */
int root_dir_entry ; /* Nummer des Root
Verzeichniseinträge */
unsigned int no_sects ; /* Anzahl der Gesamt
Sektoren */
unsigned char format_id ; /* Mediendeskriptor
Byte */
int sec_per_fat; /* Sektoren pro FAT */
int sec_per_trk; /* Sektoren pro FAT */
int no_sides ; /* Anzahl der
Seiten (Köpfe) */
int no_sp_res_sect ; /* Anzahl der versteckten
Sektoren */
unsigned char rest_code[482] ;/* Restlicher 482 Bytes Code
von DBR */
} ;
Struktur boot b;
hauptsächlich( )
{
mit einem Hinweis;
val = absread(0, 1, 0, &b); /* Für Diskette verwenden */
wenn (Wert == -1)
{
printf ( "\n Fehler beim Lesen der Festplatte...fehlerhafter Sektor\n" ) ;
Ausgang ( 1 ) ;
}
clrscr( );
Anzeigeinfo();
getch();
printf("\n BDR der Diskette wird jetzt wiederhergestellt....\n");
Wiederherstellen_mit_Werten();
printf ( "\n Datenträger erfolgreich wiederhergestellt." ) ;
Anzeigeinfo();
gebe 0 zurück;
}
/* Funktion zum Ändern der DBR-Parameter */
Wiederherstellen_mit_Werten()
{
int-Wert =0;
/* Sprungcode von 3 Bytes für Diskette */
b.code[0] = 0xEB;
b.code[1]= 0x3E;
b.code[2]= 0x90 ;
/* System-ID von 8 Bytes */
strcpy(b.system_id, "+05PSIHC");
/* Bytes pro Sektor = 512 */
b.Bytes_pro_Sek. = 512;
/* Sektor pro Cluster für 1,44 M 3,5" Diskette = 1 */
b.sec_per_clus = 1;
/* Anzahl reservierter Sektoren = 1 */
b.res_sec =1;
/* Anzahl der FAT-Kopien = 2 */
b.Fettkopien =2;
/* Anzahl der Stammverzeichniseinträge = 224 */
b.root_dir_entry =224;
/* Anzahl der Sektoren auf der Festplatte = 2880 */
b.keine_sekten =2880;
/* Mediendeskriptor-Byte für Diskette = F0 (H) */
b.format_id =0xF0;
/* Sektoren pro FAT = 9 */
b.sec_per_fat =9;
/* Sektoren pro Spur = 18 */
b.sec_pro_trk =18;
/* Anzahl der Seiten = 2 */
b.keine_seiten =2;
/* Anzahl der speziell reservierten Sektoren (oder versteckten
Sektoren) = 0 */
b.no_sp_res_sect =0;
/* Für Diskette verwenden*/
Wert = abswrite (0, 1, 0, &b);
wenn (Wert == -1)
{
printf ( "\n Schreibfehler auf der Festplatte...fehlerhafter Sektor\n" ) ;
printf ( " Die Festplatte wurde nicht wiederhergestellt." ) ;
Ausgang ( 1 ) ;
}
gebe 0 zurück;
}
Anzeigeinfo ()
{
printf ( "\n Sprungcode (Hex) = %X%X%X (H)\n",
b.code[0],b.code[1],b.code[2]);
printf ( " System-ID = %s\n",
b.system_id ) ;
printf ( " Bytes pro Sektor = %d\n",
b.Bytes_pro_Sek.) ;
printf ( " Sektoren pro Cluster = %d\n",
b.sec_per_clus );
printf ( " Reservierte Sektoren = %d\n",
b.res_sec ) ;
printf ( " FAT-Kopien = %d\n",
b.Fettkopien ) ;
printf ( " Stammverzeichniseinträge = %d\n",
b.root_dir_entry ) ;
printf ( "Anzahl der Sektoren auf der Festplatte = %u\n",
b.keine_sekten ) ;
printf("Mediendeskriptor-Byte = %X\n",
b.format_id ) ;
printf("Sektoren auf FAT = %d\n",
b.sec_per_fat ) ;
printf("Sektoren pro Spur = %d\n",
b.sec_per_trk ) ;
printf("Anzahl der Seiten = %d\n",
b.keine_seiten);
printf("Anzahl der reservierten Sektoren = %d\n",
б.no_sp_res_sect) ;
gebe 0 zurück;
}
Kodierungskommentare:
Die Bootstruktur wird verwendet, um auf den DBR zuzugreifen und Festplattenparameter zu lesen und zu schreiben. Die Funktion display_info() zeigt verschiedene Festplattenparameter an, indem sie aus dem DBR liest. Die Funktion Recover_with_values() wird zum Ändern und Wiederherstellen von DBR-Diskettenparametern verwendet.
Die von der Funktion Recover_with_values() verwendeten Werte gelten für eine 1,44 MB große, 3 ½ Zoll große DBR-Diskette. Eine Beschreibung dieser Werte finden Sie in der folgenden Tabelle:
