Wenn ich meine Konstanten so setzte:
#define BASE_STACK_SIZE 0x8000
#define VIRT_STACK_ADDR 0xBADF0000
tritt der GPF bei 0x1050F0 auf, also also am Ende meiner Syscall-Behandlungsroutine. Meine Behandlungsroutine sieht momentan so aus:
%macro save_regs 0
; alle register sichern
pushad
;segmente sichern
push ds
push es
push fs
push gs
; den kernel daten deskriptor laden
cld
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
; das kernel-pd laden
mov eax, [kernel_pd]
mov cr3, eax
; den stack des momentaten prozesses nach current_process
mov eax, [current_task]
mov [eax], esp
; alten stack nach ecx sichern
mov eax, esp
; jetzt den kernel_stack laden
; jetzt in den kernel_stack wechseln(wenn task nicht ring3, da der schon im kernel stack liegt)
mov ebx, [current_task]
mov ecx, [ebx + 12]
sub ecx, 3
jz %%l1
mov esp, [ebx + 4]
%%l1:
push eax
%endmacro
%macro rest_regs 0
pop eax
; in den stack des momentanen(evtl. auch nächsten) prozesses wechseln
mov eax, [current_task]
mov esp, [eax]
; das pd setzten
mov ebx, [current_task]
mov eax, [ebx + 8];
mov cr3, eax
;cli
;hlt
; register zurückholen
pop gs
pop fs
pop es ; <--------- HIER KOMMT DER GPF(es wird mit 0x01 beladen)
pop ds
popad
%endmacro
; syscall(push ebenfalls int_no und error_code(0), damit man auch in ihm einen prozess wechseln kann kann)
global sc
sc:
; dummy werte auf den stack
push byte 0
push byte 0x77
save_regs
; jetzt den syscall hander aufrufen
mov eax, Syscall_handler
call eax
rest_regs
; die dummy paramter vom stack nehmen
add esp, 8
iret
; wird als rücksprungaddresse für einen rpc-call benutzt, damit der stack kontant bleibt, und beendet diesen
global rpc_end_stub
rpc_end_stub:
mov eax, 0x02
pop ebx
int 0x77
Je nachdem wo ich den Stack platziere 0xE0000000 oder 0xBADF0000 kommt der GPF irgendwo beim pop'en der segment register, aber nur wenn der RPC_Handler eines Prozesses aufgerufen wird und nicht der des Kernels.
Achja der Platzt des Stacks ist reserviert, d.h keine funktion wie malloc o.ä alloziert die virtuellen speicher zwischen VIRT_STACK_ADDR und VIRT_STACK_ADDR + BASE_STACK_SIZE.
Ich hab mir auch in qemu mittels "info tlb" mal die zuordnung zwischen virtuellem und physischem Speicher angesehen, es zeigt auch keine andere virtuelle addresse auf den physischen platzt des Stacks, von da an kann ich mir diesen Fehler absolut nicht erklären. Wenn ich VIRT_STACK ADDR auf 0xF0000000 setzte kommt der GPF nur auf einer Realen Maschiene nicht in qemu/bochs.