Ich habe mir die OS-Seite von Erhard Henkes angeshen...


  • Mod

    http://www.henkessoft.de/OS_Dev/OS_Dev1.htm#mozTocId427538

    nasm boot.asm   -f bin -o boot.bin
    nasm kernel.asm -f bin -o kernel.bin
    cmd /c copy /b boot.bin + kernel.bin MyOS.bin
    partcopy MyOS.bin 0 400 -f0
    
    1. Schau dir MyOS.bin mit dem Hex-Editor an, ob alles dabei ist.
    2. Achte darauf, dass die Daten nach dem Kopieren wirklich im Bootsektor anfangen (da liegt offensichtlich dein Fehler)

    Probiere es mal mit http://www.chrysocome.net/dd anstelle rawwrite (Das verwende ich nicht mehr)

    So kopiere ich z.B. das aktuelle Image auf eine Floppy zum Booten:

    dd if=FloppyImage.img of=\\.\A:
    

    Vielleicht kann man das auf die virtuelle Floppy übertragen.

    Ansonsten verwende qemu:

    qemu.exe -fda MyOS.bin
    

    ... oder bochs: (Bochs config-Datei)

    floppya: 1_44=MyOS.bin, status=inserted
    

    oder

    floppya: 1_44=G:\OSDev\Test\MyOS.bin, status=inserted
    

    Umkopieren ist auf jeden Fall falsch. Dieses Binärformat ist bereits Rohformat, also die binären Daten, Byte für Byte, wie sie auf den ersten beiden Sektoren (jeweils 512 == 0x200 Byte) auftauchen sollen.

    Geübter Umgang mit den Tools ist bei OSDev wichtig. Probiere also bitte die ganze Kiste durch. Es gibt auch noch VBox und VMWare Player.



  • Bei Qemu kommt jetzt "Lade Kernel..." und dann hängt sich gleich das OS auf.

    ... Hab den Fehler gefunden ...

    ;kernel.asm
    times 510-($-$$) hlt  ; as alternative to db 0
    


  • Könnte man den Kernel anstatt mit C vielleicht auch in Pascal schreiben?



  • Ja, kann man. Du kannst das hier als Ansatz dafür nehmen. Alles weitere läuft so ähnlich wie in C, nur eben mit anderer Syntax. Die Pascal-Runtime steht dir erstmal nicht zur Verfügung - wenn der Compiler meckert, dass er irgendeine Funktion aus der Runtime brauch, aber nicht findet, dann musst du in der system.pas die entsprechenden Funktionen implementieren.


  • Mod

    Könnte man den Kernel anstatt mit C vielleicht auch in Pascal schreiben?

    C wurde extra für die Erstellung von Betriebssystemen geschaffen, soweit ich weiß. Pascal ist sicher auch möglich, aber man sondert sich damit ab, genau wie mit D. Dann würde ich eher C++ anpeilen.



  • Pascal und C nimmt sich nicht viel. Da bist du unter Umständen mit C++ von den Konzepten her weiter weg. Was natürlich wahr ist, ist, dass so gut wie alle Beispiele in C geschrieben sind. Lesen sollte man es also schon können.



  • taljeth schrieb:

    Pascal und C nimmt sich nicht viel. Da bist du unter Umständen mit C++ von den Konzepten her weiter weg. Was natürlich wahr ist, ist, dass so gut wie alle Beispiele in C geschrieben sind. Lesen sollte man es also schon können.

    Wer C++ kann, kann C lesen. Also wäre C++ keine schlechte Basis für einen OS-Entwickler. Wobei ich selbst sagen muss, dass ich einige Kniffe in C erst durch die Anwendung in PrettyOS gelernt habe, obwohl ich vorher schon halbwegs gut C++ konnte.



  • Ist die Menge derjenigen, die C++ wirklich beherrschen nicht so überschaubar, dass die Aussage irrelevant ist? 😉

    Ich habe schon genug Leute gesehen, die von sich behauptet haben, C++ zu können und dann an den C-Beispielen grandios gescheitert sind. Die ideale Programmiersprache für OS-Dev ist diejenige, die man in- und auswendig kennt. Wenn du mit Nebensächlichkeiten wie der Sprache oder dem Compiler kämpfen musst, wird ein sowieso schon schwieriges Projekt wie ein OS nochmal deutlich schwieriger. (Andererseits darf man das auch nicht zu sehr überbewerten: tyndur war mein erstes ernsthaftes Projekt in C)


  • Mod

    Wichtig ist, dass man am Ball und neugierig bleibt. Entweder hat man diese innere Kraft oder man hat sie nicht. Hat man sie, geht es immer weiter, und es wird nicht wirklich langweilig. 🙂



  • Erhard ich glaube ich habe einen Fehler in deinem Tutorial entdeckt:D:-P.
    Bei Seite 1 wo es um die outportb und set_cursor Funktion geht, steht, man würde an die Ports 0x0E und 0x0F Befehle senden, aber das stimmt doch gar nicht. Man sendet doch bei VGA an den Port 0x3D4 den Befehl 0x0E um dann an 0x3D5 das High Byte zu senden und dann 0x0F an 0x3D4 um dan an 0x3D5 das Low byte zu senden oder nicht? Zudem sind glaube ich auch bei der Funktion outportb die Parameter port und value vertauscht. müsste port nicht value sein und value port 😉 😃 ? Oder ich verstehe das gerade komplett falsch?
    Eine frage habe ich auch noch, was genau passiert durch den rechtsschift um 8 und dann dem UND mit 0xFF beim High byte und dem UND mit 0xFF bei dem Low Byte?

    Lg freeG


  • Mod

    kannst du bitte den code genau darstellen? IST und das, was du für richtig hältst.



  • Erhard Henkes schrieb:

    kannst du bitte den code genau darstellen? IST und das, was du für richtig hältst.

    Sorry, mein Fehler, hatte ganz vergessen, dass ja AT&T Syntax verwendet wird, bzw dass dort eben die Operanden im Vergleich zur Intel Syntax vertauscht sind. Von daher stimmt alles;-), hier trotzdem mal der Code den ich meinte. Aber wie gesagt, passt alles 😃 🙂

    inline void outportb(unsigned int port,unsigned char value)
    {
        asm volatile ("outb %%al,%%dx"::"d" (port), "a" (value));
    };
    
    void update_cursor(int row, int col)
    {
        unsigned short position = (row*80) + col;
    
        // cursor HIGH port to vga INDEX register
        outportb(0x3D4, 0x0E);
        outportb(0x3D5, (unsigned char)((position>>8)&0xFF));
    
        // cursor LOW port to vga INDEX register
        outportb(0x3D4, 0x0F);
        outportb(0x3D5, (unsigned char)(position&0xFF));
    };
    

    Lg freeG


  • Mod

    Sorry, mein Fehler, hatte ganz vergessen, dass ja AT&T Syntax verwendet wird

    Na, dann ist doch alles bestens. 🙂



  • Jap, allerdings ist mir was anderes aufgefallen. Man muss doch als Limit der GDT fürs GDT-Register die Größe der GDT in Bytes-1 angeben. In deinem Tutorial wird allerdings einfach nur 24 Byte,also 3 Einträge verwendet und nicht 23 Byte. Wieso hast du das minus 1 weggelassen?

    Lg freeG



  • Strenggenommen ist das Limit damit ein Byte zu groß, aber weh tut das nicht besodners: Es wird ja immer nur auf ganze GDT-Einträge zugegriffen und damit hat der nächste immer noch sieben Bytes außerhalb des Limits liegen und kann deswegen nicht versehentlich benutzt werden.


  • Mod

    Danke für den Hinweis. 🙂



  • Erhard Henkes schrieb:

    Danke für den Hinweis. 🙂

    Kein Ding 😉 😃



  • fr33g schrieb:

    Erhard Henkes schrieb:

    kannst du bitte den code genau darstellen? IST und das, was du für richtig hältst.

    Sorry, mein Fehler, hatte ganz vergessen, dass ja AT&T Syntax verwendet wird, bzw dass dort eben die Operanden im Vergleich zur Intel Syntax vertauscht sind. Von daher stimmt alles;-), hier trotzdem mal der Code den ich meinte. Aber wie gesagt, passt alles 😃 🙂

    inline void outportb(unsigned int port,unsigned char value)
    {
        asm volatile ("outb %%al,%%dx"::"d" (port), "a" (value));
    };
    
    void update_cursor(int row, int col)
    {
        unsigned short position = (row*80) + col;
    
        // cursor HIGH port to vga INDEX register
        outportb(0x3D4, 0x0E);
        outportb(0x3D5, (unsigned char)((position>>8)&0xFF));
    
        // cursor LOW port to vga INDEX register
        outportb(0x3D4, 0x0F);
        outportb(0x3D5, (unsigned char)(position&0xFF));
    };
    

    Lg freeG

    Nochmal zu dem Thema: Ich wusste doch dass ich mir aber sicher war, dass da irgendwas falsch ist... 😃
    Du schreibst im Tutorial an der oben genannten Stelle, man würde Befehle an die Ports 0x0E und 0x0F senden. Dies ist aber ja nicht der Fall, stattdessen sendet man Befehle an die Ports 0x3D4 und 0x3D5, wobei 0x0E und 0x0F nur zwei der vier Befehle sind, die an die genannten Ports gesendet werden.

    Lg freeG


  • Mod

    Thx. Habe den letzten Punkt korrigiert.



  • Erhard Henkes schrieb:

    Thx. Habe den letzten Punkt korrigiert.

    Habs gesehen 😉


Anmelden zum Antworten