Autor Thema: syscall  (Gelesen 6202 mal)

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« am: 26. January 2009, 14:03 »
Hallo zusammen,

da ich jetzt mein malloc/free fast fertig habe, wollte ich mich um die Syscalls kümmern.
Wie kann man das am besten realisieren?
Ich schreibe einen Microkernel, also muss ich wenn ein Treiber angesprochen wird die Directory für den Treiber ändern.
Das ist ja noch nicht das Problem.
Der Prozess, der die Kommunikation mit dem Kernel möchte, muss ja ein Interrupt auslösen (z.B. auf 0x80).
Nun habe ich das Problem, dass der Kernel nicht weiß, was der Prozess nun mit dem Interrupt erreichen wollte.
Also muss der Prozess mitsenden was gemacht werden soll.
Das Problem ist, wie übertrage ich das?
Wenn ich vom User- in den Kernelspace wechsel, ändert sich ja auch der Stackpointer.
Also kann ich die Daten ja nicht in den Stack legen.
Welche Register bleiben denn in dem Prozessor erhalten, wenn der Sprung geschieht?
Wie genau muss ich mir das mit den Software-Interrupts vorstellen?
Wie sehen die Befehle für den Interrupt aus und wie springe ich danach wieder zurück?

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

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #1 am: 26. January 2009, 15:03 »
Man speichert im Interrupthandler einfach den gesamten Status des momentanen Prozesses/Threads. Das musst du sowieso für nicht-Syscalls (zB IRQs, die sollen ja vom Prozess/Thread unbemerkt ablaufen). Dann schaust du dir in deinem Syscall-Handler eben den gespeicherten Status an und entscheidest zB anhand des eax Registers welcher der Funktionen jetzt ausgeführt werden soll. Weitere Parameter kann man in weiteren Registern unterbringen...
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: 27. January 2009, 08:20 »
Ok.
Gibt es trotzdem eine Möglichkeit direkt vom Ring 3 in 1 oder 2 zu springen?
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #3 am: 27. January 2009, 09:40 »
Ring 1 und 2 verwendet normalerweise niemand. Ansonsten sollte das imho über Interrupt/Trap/Call/Task-Gate gehen. Zumindest sehe ich da keine Probleme. Wobei wie gesagt es keinen Sinn macht Ring 1 und 2 zu verwenden.
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

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 27. January 2009, 12:19 »
Och, man kann sich da sicher lustige Konzepte mit Ring 1 und 2 ausdenken. ;)

Aber vielleicht sollte man das erst machen, wenn man das einfache am Laufen hat und versteht, wie das überhaupt alles funktioniert, ja.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #5 am: 27. January 2009, 17:38 »
Och, man kann sich da sicher lustige Konzepte mit Ring 1 und 2 ausdenken. ;)
Dann erzähl mal. m.E. krieg man nämlich alles auch ohne Ring 1 und 2 hin :wink:
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

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 27. January 2009, 19:58 »
Ja, ohne Frage. qemu läuft in Ring 3, q.e.d.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 27. January 2009, 20:57 »
Naja gut.
Ich dachte nur, dass es vllt nicht schlecht ist, die Treiber vom User zu kapseln und den Treibern mehr Hardwarerechte gibt.
Wodurch ich den Traffic mit dem Kernel senken wollte (ohneauf einen monolithischen Kernel zu wechseln).
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #8 am: 27. January 2009, 21:26 »
Man kann in der I/O Permission Bitmap (Teil des TSS) die Rechte an bestimmten I/O Ports vergeben, d.h. auf Taskebene bestimmte Ports direkt erlauben bzw. nicht erlauben. Dazu braucht man keinen Ring1 oder Ring2.
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 #9 am: 27. January 2009, 21:30 »
Wie mache ich den Userprogrammen diese Callgates denn bekannt?
Also die werden ja erst zur Laufzeit gebildet. Dadurch muss ich im Prinzip jedem Userprogramm eine Liste von Callgates bereitstellen, oder?
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #10 am: 27. January 2009, 22:30 »
Warum willst du nun doch Callgates? Interruptgates reichen doch vollkommen aus.
Ansonsten, indem du sie in die GDT einträgst, zB an fixen Positionen, ansonsten schreibst du irgendwo in den Speicher wo jeder lesend zugreifen kann zu welcher Funktion den welches Callgate gehört oder sowas.
Aber wie gesagt, Interruptgates sind vollkommen ausreichend. Ein Interrupt für syscalls und gut is.
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 #11 am: 27. January 2009, 22:44 »
Ja gut, ich dachte mir nur, dass callgates auch net schlecht wären für manche funktionen.
Also muss ich jedem Prozess der erzeugt wird eine Liste von syscalls liefern, oder wie?
Der sucht sihc aus der Liste dann den passenden raus und löst den Interrupt aus.
Oder betritt eben das callgate
« Letzte Änderung: 27. January 2009, 22:47 von rizor »
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

rizor

  • Beiträge: 521
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 30. January 2009, 23:50 »
Ich habe da nochmal eine Frage.
Wie löse ich das mit den Syscalls?
Wenn ich einen User-Process kompiliere, kenne ich die Syscalls ja noch nicht.
Wie mache ich das?
Wird das über dynamic-libraries gemacht?
Wenn ja, wie realisiere ich diese?
« Letzte Änderung: 30. January 2009, 23:51 von rizor »
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #13 am: 31. January 2009, 10:54 »
Wie löse ich das mit den Syscalls?
Wenn ich einen User-Process kompiliere, kenne ich die Syscalls ja noch nicht.
Fixe nummern für den Syscall. Am Beispiel meines OS: kernel/syscall.cpp ist die Datei innerhalb des Kernels die die Funktionen für die Syscalls implementiert. Man sieht oben das Array in dem Funktionspointer gespeichert werden. Dieses wird indiziert durch die Syscallnummer (die in eax nach dem Syscall steht) und der dortige Funktionspointer aufgerufen. Userspaceseitig sind die Syscallnummern in der libkernel/syscall.h als Makros definiert. Diese Liste _muss_ während dem kompilieren mit dem Array im Kernel übereinstimmen, ansonsten kommt natürlich Murks raus. Das wäre die Welt ohne shared-libraries. Wenn man die mal hat, dann kann man die userspaceseitigen Implementation der syscalls (bei mir in libkernel/syscall.c) in eine shared-library auslagern, dann muss nur noch während des Kompilierens der shared-library die Liste im Kernel mit den verwendeten defines im userspace übereinstimmen und man muss falls sich da was im Kernel ändert nur diese Library und den Kernel selbst austauschen.
« Letzte Änderung: 31. January 2009, 10:59 von bluecode »
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 #14 am: 19. February 2009, 16:58 »
Ich habe mich gerade näher mit der Syscall-Implementierungen beschäftigt.
Mittlerweile bin ich soweit, dass ich ein paar Syscalls registriert habe.
Nun hab ich nur noch zwei Verständnisfragen:
- Wie müssen die Flags für die IDT denn aussehen, dass jeder diesen Interrupt auslösen darf?
- Wenn der Interrupt ausgelöst wurde, dann wird der Prozessorstatus ja auf den Stack gepusht. Welcher Stack ist das? Der Kernelstack?
In der Statusübergabe müsste ich dann doch nur noch den Stack des Prozesses abarbeiten und dann hätte ich doch alle relevanten Informationen, oder?
Der Stack, den ich übergeben bekomme, müsste doch ein Pointer sein, oder?
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #15 am: 20. February 2009, 11:35 »
- Wie müssen die Flags für die IDT denn aussehen, dass jeder diesen Interrupt auslösen darf?
0xEE

Zitat
- Wenn der Interrupt ausgelöst wurde, dann wird der Prozessorstatus ja auf den Stack gepusht. Welcher Stack ist das? Der Kernelstack?
Der Kernelstack wie er in ss0:esp0 in dem TSS angegeben ist.

Zitat
In der Statusübergabe müsste ich dann doch nur noch den Stack des Prozesses abarbeiten und dann hätte ich doch alle relevanten Informationen, oder?
Man kann die Parameterübergabe auch über die Register machen, dann braucht man (evtl.) überhaupt nicht den Userspace Stack anschauen.

Zitat
Der Stack, den ich übergeben bekomme, müsste doch ein Pointer sein, oder?
öh... hä? Der userspace-Stackpointer (also esp) wird auf den Kernelstack gepusht, falls du das meinst...
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 #16 am: 20. February 2009, 12:49 »
Ja, das meinte ich.
Danke, habe mich sehr undurchsichtig ausgedrückt.
Programmiertechnik:
Vermeide in Assembler zu programmieren wann immer es geht.

 

Einloggen