| Zeile 1: | Zeile 1: | ||
==Vorwort== | ==Vorwort== | ||
| − | Da im letzten Tutorial (Protected Mode) es leider nicht mehr ganz geklappt hat schiebe ich dieses Tutorial noch nach. Hier werde ich zeigen wie man einen eigenen Kernel der in C geschrieben ist starten kann. Auch dazu ist etwas arbeit nötig und meine Methode ist vielleicht nicht die bequemste, jedoch funktioniert sie und ich werde auch wieder selbst geschriebene Tools bereitstellen umd die Arbeit möglichst zu erleichtern. | + | Da im letzten Tutorial ([[Protected Mode]]) es leider nicht mehr ganz geklappt hat schiebe ich dieses Tutorial noch nach. Hier werde ich zeigen wie man einen eigenen [[Kernel]] der in [[C]] geschrieben ist starten kann. Auch dazu ist etwas arbeit nötig und meine Methode ist vielleicht nicht die bequemste, jedoch funktioniert sie und ich werde auch wieder selbst geschriebene Tools bereitstellen umd die Arbeit möglichst zu erleichtern. |
==Booten== | ==Booten== | ||
| − | Das erste was passieren muss ist das der PC booten muss. Es gibt viele bereits fertig Bootloader die einen großen Umfang an Funktionen bieten. Ich bin jedoch eher der Ansicht das man es selbst machen sollte. Da ich mir einen eigenen Bootloader geschrieben habe, der eigentlich recht bequem funktioniert, stützte ich mich hier darauf. Der Bootloader läd eine binäre Datei aus dem Root-Directory einer Diskette, welche mit dem FAT12 Dateisystem arbeitet. Daher kann man seinen Kernel später ganz bequem auf die Diskette kopieren und starten lassen. Da ich den Bootloader bereits in einem Tutorial vorgestellt habe, werde ich hier nicht näher darauf eingehen, sondern lediglich am Ende nochmal den Quelltext bereitstellen. | + | Das erste was passieren muss ist das der PC booten muss. Es gibt viele bereits fertig [[Bootloader]] die einen großen Umfang an Funktionen bieten. Ich bin jedoch eher der Ansicht das man es selbst machen sollte. Da ich mir einen eigenen Bootloader geschrieben habe, der eigentlich recht bequem funktioniert, stützte ich mich hier darauf. Der Bootloader läd eine binäre Datei aus dem Root-Directory einer Diskette, welche mit dem [[FAT12]] [[Dateisystem]] arbeitet. Daher kann man seinen Kernel später ganz bequem auf die Diskette kopieren und starten lassen. Da ich den Bootloader bereits in einem Tutorial vorgestellt habe, werde ich hier nicht näher darauf eingehen, sondern lediglich am Ende nochmal den Quelltext bereitstellen. |
| Zeile 10: | Zeile 10: | ||
Es mag komisch klingen, aber man benötigt, zumindest für meine Version, zwei Kernel. Streng genommen sind es sogar drei. Dabei bestehen zwei Kernel aus reinem Assembler und der andere ist dann der eigentliche, in C geschriebene Kernel, auf den wir hinaus wollen. | Es mag komisch klingen, aber man benötigt, zumindest für meine Version, zwei Kernel. Streng genommen sind es sogar drei. Dabei bestehen zwei Kernel aus reinem Assembler und der andere ist dann der eigentliche, in C geschriebene Kernel, auf den wir hinaus wollen. | ||
| − | Der erste Kernel dient lediglich dazu eine kleine Global Deskriptor Table(GDT) einzurichten und in den Protected Mode zu schalten. Das ist nämlich Grundvorraussetzung, wenn wir im weiteren mit einem C-Kernel arbeiten möchten. | + | Der erste Kernel dient lediglich dazu eine kleine Global Deskriptor Table ([[GDT]]) einzurichten und in den Protected Mode zu schalten. Das ist nämlich Grundvorraussetzung, wenn wir im weiteren mit einem C-Kernel arbeiten möchten. |
Der zweite Kernel (wenn man das so bezeichnen kann) ist ein kleiner Zwang den mit der Linker aus den GNU Binutils auferzwungen hat. Dieser erklärte mir nämlich ganz höflich das er sich nicht dazu überreden lässt eine Objektdatei zu linken, die teilweise 16-Bit Code enthält. Und diesen 16-Bit Code benötigen wir in dem ersten Kernel, welcher in den Protected Mode schaltet. Dort sind wir nämlich, solange wir den Protected Mode noch nicht entgültig aktiviert haben, im Real-Mode und haben somit auch 16-bit Code. | Der zweite Kernel (wenn man das so bezeichnen kann) ist ein kleiner Zwang den mit der Linker aus den GNU Binutils auferzwungen hat. Dieser erklärte mir nämlich ganz höflich das er sich nicht dazu überreden lässt eine Objektdatei zu linken, die teilweise 16-Bit Code enthält. Und diesen 16-Bit Code benötigen wir in dem ersten Kernel, welcher in den Protected Mode schaltet. Dort sind wir nämlich, solange wir den Protected Mode noch nicht entgültig aktiviert haben, im Real-Mode und haben somit auch 16-bit Code. | ||
| Zeile 44: | Zeile 44: | ||
Dazu wird folgender Assemblercode benötigt: | Dazu wird folgender Assemblercode benötigt: | ||
| + | <asm> | ||
[Bits 32] | [Bits 32] | ||
extern _main | extern _main | ||
| Zeile 51: | Zeile 52: | ||
Stop: | Stop: | ||
jmp stop | jmp stop | ||
| − | + | </asm> | |
Auch hier wieder eine Erläuterung: | Auch hier wieder eine Erläuterung: | ||
| Zeile 92: | Zeile 93: | ||
Der C-Kernel kann Anfangs erstmal sehr einfach aussehen. Daher genügt erstmal folgender Code: | Der C-Kernel kann Anfangs erstmal sehr einfach aussehen. Daher genügt erstmal folgender Code: | ||
| + | <c> | ||
int main() | int main() | ||
{ | { | ||
return(0); | return(0); | ||
} | } | ||
| + | </c> | ||
Es gibt viele Leute die sich darum streiten ob die Funktion nun "void" oder "int" als Returnwert haben soll oder muß. Laut Standard soll es "int" sein, was auch Sinn macht, da darüber ein Return-Wert an das Betriebssystem zurückgegeben werden kann, anhand dessen das Betriebssystem feststellen kann, ob die Anwendung korrekt oder mit einem Fehler beendet wurde. | Es gibt viele Leute die sich darum streiten ob die Funktion nun "void" oder "int" als Returnwert haben soll oder muß. Laut Standard soll es "int" sein, was auch Sinn macht, da darüber ein Return-Wert an das Betriebssystem zurückgegeben werden kann, anhand dessen das Betriebssystem feststellen kann, ob die Anwendung korrekt oder mit einem Fehler beendet wurde. | ||
| Zeile 115: | Zeile 118: | ||
Erweitern wir nun also wie folgt den C-Code: | Erweitern wir nun also wie folgt den C-Code: | ||
| + | <c> | ||
int main() | int main() | ||
{ | { | ||
| Zeile 129: | Zeile 133: | ||
return(0); | return(0); | ||
} | } | ||
| + | </c> | ||
Eigentlich sollte ich erwarten, das man C kann, wenn man schon das Tutorial liest. Dennoch will ich nicht so sein und erkläre auch hier kurz was passiert: | Eigentlich sollte ich erwarten, das man C kann, wenn man schon das Tutorial liest. Dennoch will ich nicht so sein und erkläre auch hier kurz was passiert: | ||