Autor Thema: kontrolliert zurück in den 16bit-Modus  (Gelesen 6624 mal)

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« am: 14. April 2010, 16:48 »
Nabend zusammen,

ich möchte, dass mein System zurück in den realmode springt, dort arbeitet und dann wieder zurück kommt.
Dabei möchte ich nicht zwei Dateien laden, sondern einfach 16-bit code und 32-bit code zusammenpacken, falls das geht.
Danach soll der 16-bit Code unter die 1MB Grenze geladen werden und dann soll der Code ausgeführt werden.
Ist das möglich?

Danke.

Gruß
rizor
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #1 am: 14. April 2010, 18:57 »
Ja das geht. Zumindest hat FreakyPenguin es geschafft seinen trampoline code für SMP-Systeme direkt mitzuassemblieren. Der entsprechende Patch so so aus:

Zitat
diff --git a/src/loader/loader.ld b/src/loader/loader.ld
 30 index 711495b..df7e061 100644
 31 --- a/src/loader/loader.ld
 32 +++ b/src/loader/loader.ld
 33 @@ -13,10 +13,16 @@ SECTIONS
 34                *(.data*)^M
 35                *(.rodata*)^M
 36        }^M
 37 -      .bss :^M
 38 +^M
 39 +      trampoline_start = LOADADDR(.trampoline);^M
 40 +      .trampoline 0x7000 : AT(ADDR(.data) + SIZEOF(.data))^M
 41 +      {^M                                                                                         
 42 +              *(.trampoline*)^M
 43 +      }^M
 44 +      trampoline_end = LOADADDR(.trampoline) + SIZEOF(.trampoline);^M
 45 +      .bss (LOADADDR(.trampoline) + SIZEOF(.trampoline)) :^M
 46        {^M
 47                *(.bss*)^M
 48        }^M
 49 -^M
 50  }^M
 51  ^M
285 diff --git a/src/loader/trampoline.S b/src/loader/trampoline.S
286 new file mode 100644
287 index 0000000..7461041
288 --- /dev/null
289 +++ b/src/loader/trampoline.S
290 @@ -0,0 +1,45 @@
291 +.section .trampoline,"aw",@progbits

Das wesentliche (fett) ist wohl die Flags der Sektion anzupassen (das ist AT&T-Syntax), außerdem muss man die Linkadresse im Linkerscript natürlich anpassen, zumindest die physische.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 16. April 2010, 12:19 »
ah, danke.
Dann werde ich mich daran mal versuchen.
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 16. April 2010, 18:47 »
Falls ich mal meinen Senf dazugeben darf. Am besten macht sich das wenn man sowas komplett in Assembler schreibt und dann in z.B. NASM nur den Modus angibt (z.b. use16 und use32). Ich habe genau sowas genutzt um in meinem Loader auch aufs BIOS zugreifen zukönnen und trotzdem alles schön in 32bit C-Code zu schreiben.

chris12

  • Beiträge: 134
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 16. April 2010, 19:00 »
dann bist du aber nicht im protected mode, sonder im realmode. wie es kommt, dass dein 32 bitcode trotzdem funzt weiß ch nicht. auf jeden fall bist du, so denke ich mal, solange nicht im pmode, solange du noch die bios ints nutzen kannst
OS? Pah! Zuerst die CPU, dann die Plattform und _dann_ das OS!

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 16. April 2010, 19:03 »
Ich hätte mich besser ausdrücken sollen. Ich springe zurück in den RMode, calle den BIOS-Code und springe zurück in den PMode. So muss ich meinen Loader nicht komplett in ASM coden (was ich vorher gemacht habe) und es macht die Sache halt wesentlich einfacher.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 17. April 2010, 17:59 »
Wie darf ich mir das vorstellen?
Du springst in den RMode, machst die BIOS-Interrupts und gehst mit den Ergebnissen zurück in den PMode?
Die Werte in den Registern bleiben bestehen?

Die Idee finde ich noch besser.
Wie kannst du dem Compiler das denn beibringen, dass er 16-bit-Code in einer 32-bit-Umgebung verwenden soll?
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 17. April 2010, 23:31 »
Ich hab von C aus ne Funktion callBIOS(uint32t *eax, uint32t *ebx, ...) wo du halt Pointer auf die Register (Vars dafür) übergibst. Diese dienen als Eingabe und gleichzeitig als Ausgabe, als Rückgabewert der Funktion habe ich uint32t und gebe die Flags zurück (ist gerade bei BIOS Funktionen wichtig).

Die Funktion habe ich in Assembler geschrieben, zusammengefasst springe ich zurück in den RMode hole die Register vom Stack, rufe den BIOS Int auf, ist dieser fertig packe ich die Register und die Flags wieder auf den Stack und springe zurück in den PMode.

Es ist halt wichtig das du nicht am PIT und nicht am PIC rumspielst solange du sowas machen willst (obwohl ich den PIT solange ich im PMode von meinem eigenem Handler aufrufen lasse).

Wenn du willst könnte ich dir auch den Code als (schlecht kommentiertes) Bsp. geben.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 18. April 2010, 15:35 »
Die Frage, die sich mir stellt, ist wie du das ganze linkst.
Ich kenne kein Flag, dass es dem Linker ermöglicht 16-bit und 32-bit-Code zu linken.
Wie machst du das ganze denn?
Liegen die Methoden in eine Sektion, die du dann einfach unter die 1MB-Grenze kopierst?
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 18. April 2010, 16:42 »
Deswegen musst du das ganze ja in Assembler machen, dem ist es herzlich egal ob er nun die 16bit Variante oder die 32bit Variante von dem Opcode codieren soll und da ich das ganze nur in meinem Loader verwende bin ich auch immer unter der 1MiB Grenze.

Das ganze sieht dann in etwa so aus:
use32
code
...
Sprung in den RMode
use16
.rmode:
code
Sprung in den PMode
use32
.pmode:
Der Linker sieht dann ganz normal eine Elf-Objektdatei und weiß gar nicht das da auch 16bit Code drin ist.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #10 am: 18. April 2010, 16:58 »
Die Frage, die sich mir stellt, ist wie du das ganze linkst.
Ich kenne kein Flag, dass es dem Linker ermöglicht 16-bit und 32-bit-Code zu linken.
Wie machst du das ganze denn?
Siehe den Patch von FreakyPenguin in meinem Beitrag oben. :wink:

Zitat
Liegen die Methoden in eine Sektion, die du dann einfach unter die 1MB-Grenze kopierst?
exakt das muss man dann machen, jo

edit: Das ganze hat mit Assembler herzlich wenig zu tun. Das einzige Problem mit 16Bit und C/C++ ist wohl eher einen Compiler zu finden, der das unterstützt.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 18. April 2010, 17:05 »
Zitat von: blucode
Das ganze hat mit Assembler herzlich wenig zu tun. Das einzige Problem mit 16Bit und C/C++ ist wohl eher einen Compiler zu finden, der das unterstützt.
Wieso hat das ganze nichts mit Assembler zu tun? Alleine schon um in den RMode aus dem PMode zurück zu springen brauchst du Assembler, weil der Compiler weder das CR0 Register noch nen Sprung den du dafür brauchst kennt! Also brauchst du sehr wohl Assembler und willst du dann noch nen BIOS Interrupt aufrufen musst du bestimmte Register mit einem bestimmten Inhalt füllen (Assembler) und du musst den Interrupt aufrufen (Assembler).

Also Mode Wechsel sind immer mit Assembler verbunden (selbst wenn du es nur über Inline-Assembler machst, bleibt es Assembler)!

Edit::

Selbst in dem Patch den du ansprichst sieht man eindeutig das es über Assembler gelöst wurde, denn die Datei mit dem Code heißt trampoline.S, was eine Assemblerdatei ist. Man bekommt GCC dazu 16bit Code zu generieren (bzw. GAS) nur funktioniert das nicht so richtig.
« Letzte Änderung: 18. April 2010, 17:07 von FlashBurn »

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #12 am: 18. April 2010, 19:33 »
Zitat von: blucode
Das ganze hat mit Assembler herzlich wenig zu tun. Das einzige Problem mit 16Bit und C/C++ ist wohl eher einen Compiler zu finden, der das unterstützt.
Wieso hat das ganze nichts mit Assembler zu tun? Alleine schon um in den RMode aus dem PMode zurück zu springen brauchst du Assembler, weil der Compiler weder das CR0 Register noch nen Sprung den du dafür brauchst kennt! Also brauchst du sehr wohl Assembler und willst du dann noch nen BIOS Interrupt aufrufen musst du bestimmte Register mit einem bestimmten Inhalt füllen (Assembler) und du musst den Interrupt aufrufen (Assembler).

Also Mode Wechsel sind immer mit Assembler verbunden (selbst wenn du es nur über Inline-Assembler machst, bleibt es Assembler)!
Die vorgehensweise beim Linken hat herzlich wenig mit Assembler zu tun (du hast ja m.E. auf die Frage zum Linken geantwortet).

Zitat
Selbst in dem Patch den du ansprichst sieht man eindeutig das es über Assembler gelöst wurde, denn die Datei mit dem Code heißt trampoline.S, was eine Assemblerdatei ist. Man bekommt GCC dazu 16bit Code zu generieren (bzw. GAS) nur funktioniert das nicht so richtig.
Das Prinzip ist unabhängig von Assembler, zumindest wenn man gcc zum Setzen der Sektionsflags bekommt, was ich nicht nachgesehen habe, aber sehr wahrscheinlich möglich ist.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 18. April 2010, 19:53 »
Zitat von: bluecode
...(du hast ja m.E. auf die Frage zum Linken geantwortet).
Auch. Aber eigentlich mehr wie du es hinbekommst ohne dich verrenken zu müssen. Das wichtigste und schwierigste ist halt in den RMode und wieder zurück in den PMode zu kommen. Wie man den Code dann in eine Objektdatei bekommt ist relativ einfach (und ich finde weiterhin am einfachsten, wenn man es über eine Assemblerobjektdatei löst, aber jedem das Seine).

Das eigentlich größte Problem (vorallem am Linken) ist, dass man keine Symbole benutzen darf (die vom Linker aufgelöst werden müssen), während man 16bit Code schreibt, denn das Mixen von 16bit und 32bit Offsets kann der Linker nicht (ich habs probiert ;) ).

@bluecode

Ich denke mal wir haben aneinander vorbei geredet. Du meinst das Linken und ich wie man den Code schreibt.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #14 am: 18. April 2010, 20:23 »
Das eigentlich größte Problem (vorallem am Linken) ist, dass man keine Symbole benutzen darf (die vom Linker aufgelöst werden müssen), während man 16bit Code schreibt, denn das Mixen von 16bit und 32bit Offsets kann der Linker nicht (ich habs probiert ;) ).
FreakyPenguin hat es offensichtlich auch probiert (für seinen SMP-Code) und es muss wohl funktioniert haben.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

FlashBurn

  • Beiträge: 844
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 18. April 2010, 20:32 »
Zitat von: blucode
FreakyPenguin hat es offensichtlich auch probiert (für seinen SMP-Code) und es muss wohl funktioniert haben.
Ohne diesen Code gesehen zu haben sage ich mal nein. Du hast mich wahrscheinlich falsch verstanden.

Du kannst wunderbar Labels definieren und diese dann woanders benutzen, aber was du nicht kannst ist, Label innerhalb des 16bit Codes benutzen, die der Linker auflösen muss, dann bekommst du irgendeine Fehlermeldung von wegen das er bei 32bit ELF keine 16bit Offset auflösen kann.

Ich meine konkret:
RMode:
;16bit Code Anfang
 code
 call FOO
 code
;16bit Code Ende
RModeEnd:
Irgendwo in deinem C Code kannst du "RMode" und "RModeEnd" benutzen, aber er Linker kann die externe Adresse von "FOO" nicht auflösen, da er 16Bit Adressen/Offsets in einer 32bit ELF Datei nicht kann/will.

FreakyPenguin

  • Administrator
  • Beiträge: 301
    • Profil anzeigen
    • toni.famkaufmann.info
Gespeichert
« Antwort #16 am: 18. April 2010, 21:11 »
In meinem Code referenziere ich im 32-Bit Code auch keine 16-Bit symbole. Brauche ich ja auch nicht. Die Funktion kann in eine eigene Section, und dann kann mir der linker dafür ein 32-Bit Symbol geben, und gut ist.

Edit: Wobei ich da natürlich keine Funktionsaufrufe mit Moduswechsel habe da.
« Letzte Änderung: 18. April 2010, 21:16 von FreakyPenguin »

nachtfeuer

  • Beiträge: 1
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 20. April 2010, 08:29 »
kann man auch ohne asm mov CR0,xxxxxxx0 schreiben? ;)

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 20. April 2010, 09:20 »
Ich kenne keine Sprache, die dich ohne Inline-Assembler auf die Steuerregister zugreifen lässt, wenn du das meinst.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

 

Einloggen