Eigener Bootloader — Änderungen 7464 → 7465

Zeile 2: Zeile 2:
  
  
−
Der Weg zum eigenem Betriebssystem ist lang und steinig. Manch einer versucht als erstes einen eigenen [[Bootloader]] inklusiv [[Bootsektor]] zu entwickeln. Klar kann man sich die Arbeit auch sparen, indem man prompt zu [[GRUB]] greift. Dennoch, möchte man die Funktionsweise eines  
+
Der Weg zum eigenen Betriebssystem ist lang und steinig. Manch einer versucht als erstes einen eigenen [[Bootloader]] inklusive [[Bootsektor]] zu entwickeln. Klar kann man sich die Arbeit auch sparen, indem man einfach zu [[GRUB]] greift. Dennoch möchte man die Funktionsweise eines Bootloader verstehen können. Dies soll mit diesem Tutorial vermittelt werden.
−
Bootloader verstehen können. Dies soll mit diesem Tutorial vermittelt werden.
 
  
−
Dieses Tutorial wird in erster Linie die Vorgehensweise erläutern, die bei vielen [[Dateisystem|Dateisystemen]] identisch sind. Folglich  
+
Dieses Tutorial wird in erster Linie die Vorgehensweise erläutern, die bei vielen [[Dateisystem|Dateisystemen]] identisch sind. Folglich wird hier auch kein kompletter Source-Code eines Bootloader gelistet. Grundkenntnise in [[Assembler]] sind für dieses Tutorial allerdings Voraussetzung, so auch der Umgang mit einem Assembler und einem [[Linker]].
−
wird hier auch kein kompletter Source-Code eines Bootloader gelistet. Grundkenntnise in [[Assembler]] sind für dieses Tutorial allerdings  
 
−
Voraussetzung, so auch der Umgang mit einem Assembler und einem [[Linker]].
 
  
−
Auch in Assembler sollte man sauber programmieren und nicht scheuen, Strunkturen und Variablen statt Offset-Konstanten zu verwenden,  
+
Auch in Assembler sollte man sauber programmieren und nicht scheuen, Strunkturen und Variablen statt Offset-Konstanten zu verwenden, besonders beim [[Boot-Parameter-Block]].
−
besonders beim [[Boot-Parameter-Block]].
 
 
   
 
   
  
Zeile 16: Zeile 12:
 
Der [[Bootprozess]] wird ja bereits an anderer Stelle beschrieben, jedoch wird dort nicht näher ins Detail gegangen. Dies wird nun an dieser Stelle nun nachgeholt.
 
Der [[Bootprozess]] wird ja bereits an anderer Stelle beschrieben, jedoch wird dort nicht näher ins Detail gegangen. Dies wird nun an dieser Stelle nun nachgeholt.
  
−
Ausgangspunkt ist, dass das [[BIOS]] bereits den ersten Sektor von unserem Datenträger geladen hat und nach einer Überprüfung der Signatur die Kontrolle an diesem abgibt. Man beachte, das der erste Sektor bei Festplatten für gewöhnlich der [[Master Boot Record]] ist und auf dem ebenfalls eingegangen wird, bzw. die Vorgehensweise erläutert.
+
Ausgangspunkt ist, dass das [[BIOS]] bereits den ersten Sektor von unserem Datenträger geladen hat und nach einer Überprüfung der Signatur (0x0AA55) die Kontrolle an diesem abgibt. Man beachte, das der erste Sektor bei Festplatten für gewöhnlich der [[Master Boot Record]] ist und auf dem ebenfalls eingegangen wird, bzw. die Vorgehensweise erläutert.
−
 
+
Das erste Problem, auf das man stoßen wird, ist, dass der Binärcode des Bootsektors die Größe eines Sektors nicht überschreiten darf. OK, zugegeben, bei der CD mit ihren 2048 Bytes pro Sektor und deren Dateisystem langt dieser. Auch zukünftige Festplatten mit einer physikalischen Sektorgröße von 4096 Bytes mögen dem entgegen wirken. Aber bei der Diskette, die viele am Anfang verwenden, beträgt die Sektorgröße lediglich 512 Byte. Unser Ziel ist aber keineswegs für jedes Dateisystem einen eigenen Bootloader (ausschließlich dem Bootsektor) zu entwickeln, sondern viel mehr ein universelles Modell auf die Beine zu stellen, bei dem nur der Bootsektor individuell dem Dateisystem vorliegt und der Bootloader (Binärdatei) für alle unterstützten Dateisystemen gleich bleibt.
−
Die Falle in der man tappen wird, wenn man wild drauf los programmiert, dass der Binärcode des Bootsektors die 512-Byte-Grenze überschreiten wird. OK, zugegeben, bei der CD mit ihren 2048 Bytes pro Sektor und deren Dateisystem langt dieser. Auch zukünftige Festplatten mit einer physikalischen Sektorgröße von 4096 Bytes mögen dem entgegen wirken. Unser Ziel ist aber keineswegs für jedes Dateisystem einen eigenen Bootloader (ausschließlich dem Bootsektor) zu entwickeln, sondern viel mehr ein universelles Modell auf die Beine zu stellen, bei dem nur der Bootsektor individuell dem Dateisystem vorliegt und der Bootloader (Binärdatei) für alle unterstützten Dateisystemen gleich bleibt.
 
  
  
Zeile 28: Zeile 23:
 
* Stage 2: Bootloader
 
* Stage 2: Bootloader
  
−
Manch einer würde hier jetzt die Frage stellen, ob es wirklich sinnvoll ist, auch den MBR zu entwickeln. Wie schon anfangs erwähnt, wollen wir den Bootloader im Detail verstehen können, also machen wir keine halben Sachen. Dennoch, ganz so verkehrt ist die Frage allerdings nicht, denn meine Disketten haben für gewöhnlich keinen MBR.
+
Manch einer würde hier die Frage stellen, ob es wirklich sinnvoll ist, auch den MBR zu entwickeln. Wie schon anfangs erwähnt, wollen wir den Bootloader im Detail verstehen können, also machen wir keine halben Sachen. Dennoch, ganz so verkehrt ist die Frage allerdings nicht, denn Disketten haben für gewöhnlich keinen MBR.
  
  
Zeile 101: Zeile 96:
 
Gut gut, leider fehlt hier noch der einscheidene Sourcecode, aber den wirst du dir selbst zusammen frickeln müssen. Du wirst hier lediglich ein Umschreibung dessen finden, wie der MBR vom Programm her funktionieren sollte.
 
Gut gut, leider fehlt hier noch der einscheidene Sourcecode, aber den wirst du dir selbst zusammen frickeln müssen. Du wirst hier lediglich ein Umschreibung dessen finden, wie der MBR vom Programm her funktionieren sollte.
  
−
# Am Anfang sollte vor allem das DS richtig initialisiert werden und wenn du der Meinung ist, das DS = 0x07C0 sein sollte, liegst du völlig richtig. Den Stack könntest du aber nach deinen Belieben einrichten, aber vergesse dabei nicht den Interrupt dafür zu sperren.
+
# Am Anfang sollte vor allem das DS richtig initialisiert werden und wenn du der Meinung ist, das DS = 0x07C0 sein sollte, liegst du völlig richtig. Den Stack könntest du aber nach deinen Belieben einrichten, aber vergiss dabei nicht den Interrupt dafür zu sperren.
 
# Wo möglich ist dir schon aufgefallen, dass der MBR an die gleiche Adresse geladen wurde, wo üblich auch der Bootsektor geladen wird. Um diese Kompatiblität zu waren, solltest du ebenfalls den Bootsektor der aktiven Partition an genau dieser Adresse laden. Also was musst du jetzt tun? Richtig! Du musst den MBR im RAM verschieben und einen Sprung an die neue Adresse durchenführen, quasi ein Far-Jump ist erforderlich.
 
# Wo möglich ist dir schon aufgefallen, dass der MBR an die gleiche Adresse geladen wurde, wo üblich auch der Bootsektor geladen wird. Um diese Kompatiblität zu waren, solltest du ebenfalls den Bootsektor der aktiven Partition an genau dieser Adresse laden. Also was musst du jetzt tun? Richtig! Du musst den MBR im RAM verschieben und einen Sprung an die neue Adresse durchenführen, quasi ein Far-Jump ist erforderlich.
 
# Jetzt fangen wir erst richtig an. Da die Partitionstabelle nur maximal 4 Partitionen aufnehmen kann, laden wir unseren Zähler mit den Wert 4. Den Indexpointer setzen wir auf den Anfang der Partitionstabelle. Jetzt durchsuchen wir die Partitionstabellen nach einer als aktiv markierten Partition, welche mit einem Bootflag = 0x80 als solche markiert ist.
 
# Jetzt fangen wir erst richtig an. Da die Partitionstabelle nur maximal 4 Partitionen aufnehmen kann, laden wir unseren Zähler mit den Wert 4. Den Indexpointer setzen wir auf den Anfang der Partitionstabelle. Jetzt durchsuchen wir die Partitionstabellen nach einer als aktiv markierten Partition, welche mit einem Bootflag = 0x80 als solche markiert ist.