Bios-Interrupts im protected mode?



  • Moin,

    ich habe ein kleines bootbares Programm geschrieben. Nun möchte ich in den protected mode wechseln. Wie kann ich weiter die vom Bios initialisierten Interrupte nutzen, die doch wohl nur im real mode laufen, und wie überstehen diese eine Segmentierung?

    Muß man im protectde mode 32bit-Anweisungen verwenden oder wo ist die Grenze zwischen 16bit- und 32bit-Anweisungen?

    Danke schonmal,

    Jörn



  • Hi.

    Jörn schrieb:

    Wie kann ich weiter die vom Bios initialisierten Interrupte nutzen,[...]

    Das kannst du zB., indem du beim Aufrufen der Interruptroutine einen Taskwechsel ausfuehrst, wobei der "RealMode-Interrupt-Task" dann im V86-Modus laeuft.

    Jörn schrieb:

    die doch wohl nur im real mode laufen,

    Yup, die standard BIOS-Interrupts (VGA, Tastatur, Laufwerkszugriff) laufen nur im RealMode oder eben im V86.

    Jörn schrieb:

    und wie überstehen diese eine Segmentierung?

    Und hier weiss ich nun nicht, was du mit "Segmentierung" meinst.

    Jörn schrieb:

    Muß man im protectde mode 32bit-Anweisungen verwenden oder wo ist die Grenze zwischen 16bit- und 32bit-Anweisungen?

    Du kannst, wenn du willst, musst aber nicht.
    32Bit-Anweisungen/16Bit-Anweisungen kannst du idR. verwenden, wie du lustig bist (nur mit 32Bit-Ardressierung solltest du in 16Bit-Segmenten aufpassen 😉 ) - beides Funktioniert auch schon im RealMode.


  • Mod

    du musst allerdings aufpassen, dass du dem assembler mitteilst, ob ein bestimmter programm teil im protected mode in einem 16bit oder 32bit code segment ausgeführt wird damit er die operand_size präfixe (66h wenn mich nicht alles täuscht) korrekt setzt (im 16bit modus für 32bit operanden, im 32bit modus für 16bit operanden).



  • Mit Segmentierung meine ich, dass ich eine GDT einrichte mit verschiedenen Segmenten, also kein Paging verwende. Da sich dann die Art der Adressierung ändert, konnte ich mir nicht vorstellen, dass die Bios-Routinen noch funktionieren könnten.

    Ein Taskwechsel ist mir zum Testen ein wenig zu aufwendig. Gibt es eine einfache Routine um ASCII-Zeichen auf dem Bildschirm auszugeben?

    Gruß,

    Jörn



  • Jörn schrieb:

    Mit Segmentierung meine ich, dass ich eine GDT einrichte mit verschiedenen Segmenten, also kein Paging verwende. Da sich dann die Art der Adressierung ändert, konnte ich mir nicht vorstellen, dass die Bios-Routinen noch funktionieren könnten.

    Jo, mit der Adressierung des Protected Mode kommt dieser RealMode-Code natuerlich nicht zurecht.

    Jörn schrieb:

    Ein Taskwechsel ist mir zum Testen ein wenig zu aufwendig.

    Du koenntest natuerlich zum Aufrufen der Interrupts auch immer gleich ganz wieder in den RealMode schalten. Das waere aber wohl noch aufwaendiger.

    Jörn schrieb:

    Gibt es eine einfache Routine um ASCII-Zeichen auf dem Bildschirm auszugeben?

    Da du beim Booten normalerweise schon im 16Farben Textmodus bist, kannst du einfach in den Bildschirmspeicher bei B8000h schreiben.
    Dort liegt hintereinander immer Zeichen+Farbwert - einfach ausprobieren...



  • Da du beim Booten normalerweise schon im 16Farben Textmodus bist, kannst du einfach in den Bildschirmspeicher bei B8000h schreiben.

    Auch das sollte ja die physikalische Speicheradresse sein. Wo liegt sie denn, nachdem Segmente eingerichtet wurden?

    Gruß,

    Jörn



  • Ganz recht: B8000 ist die physikalische Speicheradresse des Graphikkartenspeichers fuer den 16Farben Textmodus.
    Wie du im Protected Mode nun Adressierst, damit diese Speicheradresse hinten rauskommt, ist deine Sache.

    Aber ein Vorschlag:
    Richte einen Descriptor in der GDT mit Basis 0, Limit 4GB (also auch 4KByte granular) usw. ein und adressier dann einfach mit dem Offset B8000h.



  • Danke, im real mode, in dem ich zu Test mal in den Textspeicher geschrieben habe, hat es gut geklappt. Allerdings habe ich nun kleine Verständnisschwierigkeiten zu Segmentregistern: In meinem Assemblerbuch, das noch Assembler für den 80286 beschreibt, werden die Segmentregister so erklärt, dass sie zur 20bit-Adressierung (bei 1MByte RAM) des RAMs benötigt werden. Die physikalische Adresse also beispielsweise ((DS << 16) | SI) ist. Nun dachte ich, dass das Ergebnis bei einem 32bit-Prozessor im real mode das gleiche sein müßte wenn ich DS=0 setze und ESI=0B800 0000h setze, da der sich ergebende Zahelnwert ja der gleiche ist. So funktioniert das aber nicht. Warum das nicht?
    Aus dem Intel-Datenblatt entnehme ich schließlich, dass im Segmentregister im protected mode ohne paging nur noch ein Index eines Eintrags in einer GDT oder LDT ist. Habe ich das richtig verstanden? Wandelt sich der Sinn des Segmentregisters wirklich so grundlegend?
    Ich bin total durcheinander.

    Gruß,

    Jörn


  • Mod

    im real modus ist 16bit adressierung standard, pass also auf, dass das codesegment im assembler auch 16bit ist (falls du .model verwendest, muss .model VOR der .386p etc stehen), dann sollte es eigentlich gehen (bin aber kein experte für real modus :). und ja, im protected modus sind segmente zunächst mal nur speicherblöcke, die irgendwo liegen können (die indirekte adressierung erlaubt es dem betriebssystem, blöcke zu verschieben um platz zu schaffen falls nötig - macht in der realität nat. niemandweil paging VIEL effizienter ist).



  • Im RealMode wird nur mit 20Bit adressiert, dh. mit 16Bit-Offsets - die Adresse wird dann wie von dir beschrieben berechnet. Das ist auch bei heutigen 64Bit-Prozessoren noch so.
    Der Protected Mode funktioniert komplett anders. Da sind die Segmentregister tatsaechlich Indexzeiger auf einen Eintrag der LDT oder GDT.
    Schau dazu mal in der FAQ nach, da steht ein Link auf ein super PM-Tutorial. 😋



  • Moin, Moin...

    Jörn schrieb:

    [...] Die physikalische Adresse also beispielsweise ((DS << 16) | SI) ist. Nun dachte ich, dass das Ergebnis bei einem 32bit-Prozessor im real mode das gleiche sein müßte wenn ich DS=0 setze und ESI=0B800 0000h setze, da der sich ergebende Zahelnwert ja der gleiche ist. So funktioniert das aber nicht. Warum das nicht? [...]

    Die Formel zur Berechnung der physikalischen Adresse ist falsch. Die Segmentadresse wird nicht um 16 Bit sondern um 4 Bit verschoben. Das entspricht einer Multiplikation mit 16.

    B800:0000 Logische Adresse aus Segment- und Offsetadresse
    -> (B800 << 4(!)) Linksshift des Segmentanteils um 4 Bits (= Multiplikation mit 16)
    -> B8000 Ergebnis des Shifts
    -> B8000 + 0000 Offset addieren
    -> B8000 physikalische Adresse

    Wenn Du im Protected Mode ein Segmentregister mit 0 besetzt, so versuchst Du auf den sogenannten NULL-DESKRIPTOR zuzugreifen. Das geht nicht. In der Tat steht in den Segmentregistern ein Index auf einen Deskriptor in der GDT oder LDT.
    Daher funktioniert Dein Zugriff mit DS=0 und ESI=B8000000 nicht. Des Weiteren ist die Adresse des Videospeichers, wie oben beschrieben, falsch berechnet.

    Ciao...


Anmelden zum Antworten