[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tyndur-devel] [PATCH] kernel2: Dokumentation der i386-Interrupt-Stubs
+ kernel2: Viel tollerer lesbarer Code weil Kommentare und so
---
src/kernel2/src/arch/i386/interrupts/int_stubs.S | 68 ++++++++++++++++++---
1 files changed, 58 insertions(+), 10 deletions(-)
diff --git a/src/kernel2/src/arch/i386/interrupts/int_stubs.S b/src/kernel2/src/arch/i386/interrupts/int_stubs.S
index 2672f3e..69caef5 100644
--- a/src/kernel2/src/arch/i386/interrupts/int_stubs.S
+++ b/src/kernel2/src/arch/i386/interrupts/int_stubs.S
@@ -35,6 +35,16 @@
.code32
+
+// Fuer jeden Interrupt wird ein eigener Einsprungspunkt definiert. Dabei
+// existieren zwei verschiedene Arten von Handlern: Solche fuer Exceptions,
+// die einen Fehlercode auf dem Stack haben, und solche fuer die uebrigen.
+// Die Stubs bringen den Stack in einen einheitlichen Zustand, speichern die
+// Interruptnummer auf den Stack und springen dann zu einem gemeinsamen
+// Handler.
+
+// Dieser Stub ist fuer Interrupts ohne Fehlercode. Als Fehlercode wird in
+// diesem Fall 0 auf den Stack gelegt.
.macro INT_STUB nr
.globl im_int_stub_\nr
im_int_stub_\nr:
@@ -43,6 +53,8 @@
jmp im_int_stub_all
.endm
+// Dieser Stub ist fuer Interrupts, die bereits einen Fehlercode auf demStack
+// haben. In diesem Fall wird nur die Interruptnummer gespeichert.
.macro INT_STUB_ERROR_CODE nr
.globl im_int_stub_\nr
im_int_stub_\nr:
@@ -50,6 +62,7 @@
jmp im_int_stub_all
.endm
+// Definition der Stubs fuer jeden Interrupt
INT_STUB 0
INT_STUB 1
INT_STUB 2
@@ -307,27 +320,47 @@ INT_STUB 253
INT_STUB 254
INT_STUB 255
+// Hier ist der Beginn des gemeinsamen Handlercodes fuer alle Interrupts.
+//
+// Wir haben an dieser Stelle im grossen und ganzen noch den Prozessorzustand
+// des Prozesses, der durch den Interrupt unterbrochen wurde. Der Stackpointer
+// des Prozesses wurde vom Prozessor ins TSS gespeichert und dafuer der dort
+// gespeicherte Kernelstack geladen.
+//
+// Auf dem Kernelstack liegen jetzt die Ruecksprungdaten (vom Prozessor beim
+// Interrupt dort abgelegt), der Fehlercode und die Interruptnummer.
+//
+// Der unterbrochene Task weiss nicht, dass ein Interrupt stattgefunden hat,
+// deswegen muss beim Ruecksprung der gesamte Prozessorzustand
+// wiederhergestellt werden. Bevor wir den Kernel oder andere Tasks Register
+// veraendern lassen, muessen wir also erst einmal den aktuellen Zustand
+// speichern. Wir benutzen dazu den Stack, der ja schon dem Kernel gehoert.
+
im_int_stub_all:
// Das rax-Register wird benoetigt, um ds und es Pushen zu koennen
pushl %eax
-
+
+ // Segmentregister auf den Stack pushen
push %gs
push %fs
xorl %eax, %eax
movw %es, %ax
pushl %eax
-
+
movw %ds, %ax
pushl %eax
-
+
+ // Allzweckregister auf den Stack
pushl %ebp
pushl %edi
pushl %esi
pushl %edx
pushl %ecx
pushl %ebx
-
+
+ // Der Task-Zustand ist hier fertig gespeichert.
+
// Ring 0 Segment-Register laden
cld
mov $0x10, %ax
@@ -335,38 +368,53 @@ im_int_stub_all:
mov %ax, %es
+ // Der aktuelle Stackpointer wird dem C-Interrupt-Handler als Parameter
+ // uebergeben. Wir haben gerade den Zustand des Gasts im Format des C-Typs
+ // interrupt_stack_frame_t auf den Stack gepusht, so dass der C-Handler
+ // bequem auf die einzelnen Register des Tasks zugreifen kann.
pushl %esp
.extern im_handler
call im_handler
-
- // Den neuen Stackpointer laden
+
+ // Der C-Handler gibt einen neuen Stackpointer fuer den Kernelstack des
+ // aktuellen Tasks zurueck (der aktuelle Task kann sich geaendert haben,
+ // wenn wir gerade einen Timer-Interrupt oder einen Syscall verarbeiten).
+ //
+ // Den neuen Stackpointer laden. Anschliessend liegt der Zustand des jetzt
+ // aktuellen Tasks auf dem Stack, den wir auslesen koennen. Anschliessend
+ // koennen wir in den Task zurueckspringen.
movl %eax, %esp
+ // Allzweckregister wiederherstellen
popl %ebx
popl %ecx
popl %edx
popl %esi
popl %edi
popl %ebp
-
-
+
+ // Segmentregister wiederherstellen
popl %eax
movw %ax, %ds
-
+
popl %eax
movw %ax, %es
pop %fs
pop %gs
-
+
+ // eax wiederherstellen
popl %eax
// Fehler- und Interruptnummer von Stack loeschen
addl $8, %esp
+
+ // Ruecksprung in den Task
iret
+
// Double Fault
.globl im_int_stub_8
.extern double_fault_tss
--
1.6.0.2