build.bat can create the image if missing, split the shell into native, posix and win32, clean up the build by moving executables into directories, the bootloader is no longer responsible to resolve drivers, fix ResolvePath, every process gets a copy of a module (dll), the child always inherits the cwd, fix function exports in posix, add unlink and exit to posix, add path translator to win32, first bugcheck.

This commit is contained in:
maksw committed 2026-05-13 09:24:16 +02:00
1 parent 0c7f461c6d
commit f80e66ecde
38 files changed
+1620 -462

No files matched your search

+51 -68
View File
@@ -37,93 +37,76 @@ KeSyscallEntry PROC
KeSyscallEntry ENDP
; ---------------------------------------------------------------------------
; Fault stubs - print a message and halt.
; Fault stubs - thin wrappers that collect the CPU exception frame and
; forward to KeFaultDispatch (C), which handles both kernel panics and
; user-process bugchecks.
;
; KeFaultDispatch signature (MS x64):
; void KeFaultDispatch(int vector, // rcx
; UINT64 rip, // rdx
; UINT64 errCode, // r8
; UINT64 cr2, // r9
; UINT64 cs) // [rsp+20h] (5th arg, on stack)
; ---------------------------------------------------------------------------
EXTERN KePanic:PROC
EXTERN KeFaultDispatch:PROC
.data
; We define separate strings to maximize the info we can print
StrKernel DB "Kernel Mode", 0
StrUser DB "User Mode", 0
MsgFaultDE DB "PANIC: Divide Error (#0) | RIP: %016llx | Mode: %s", 0Ah, 0
MsgFaultGP DB "PANIC: General Protection (#13) | RIP: %016llx | Code: %04x | Mode: %s", 0Ah, 0
MsgFaultPF DB "PANIC: Page Fault (#14) | RIP: %016llx | Code: %04x | CR2: %016llx | %s", 0Ah, 0
.code
; Allocation for a 5-argument call (MS x64):
; 32 bytes shadow space (0x00..0x1F)
; 8 bytes for 5th arg (0x20..0x27)
; Total = 0x28 bytes.
; After "and rsp,-16" rsp%16==0; sub 0x28 (40) → rsp%16==8,
; so the subsequent "call" push makes rsp 16-byte aligned at callee entry. ✓
FAULT_FRAME_SIZE EQU 28h
; ---------------------------------------------------------
; Divide Error (#0) - NO Error Code pushed by CPU
; Stack: [rsp] = RIP, [rsp+8] = CS, [rsp+16] = RFLAGS
; Divide Error (#0) - NO error code pushed by CPU
; Exception frame at entry: [rsp]=RIP [rsp+8]=CS [rsp+16]=RFLAGS
; ---------------------------------------------------------
KeFaultDE PROC
mov rdx, [rsp] ; Arg 2: RIP
mov rdx, [rsp] ; Arg2: rip
xor r8, r8 ; Arg3: errCode = 0 (no error code for #DE)
xor r9, r9 ; Arg4: cr2 = 0 (not a page fault)
mov r10, [rsp+8] ; cs (save before we clobber rsp)
mov ecx, 0 ; Arg1: vector = 0
; Determine User/Kernel mode from CS
mov rax, [rsp + 8] ; Read CS
and rax, 3 ; Isolate the bottom 2 bits (RPL)
lea r8, StrKernel
lea r9, StrUser
test rax, rax ; If 0, it's Kernel. If >0, it's User.
cmovnz r8, r9 ; Arg 3: Mode String (moves r9 into r8 if Not Zero)
lea rcx, MsgFaultDE ; Arg 1: Format string
; Safely align stack and allocate shadow space for the call
and rsp, -16 ; Force 16-byte ABI stack alignment
sub rsp, 20h ; Allocate 32 bytes of shadow space
call KePanic
and rsp, -16
sub rsp, FAULT_FRAME_SIZE
mov [rsp+20h], r10 ; Arg5: cs
call KeFaultDispatch ; _Noreturn - never returns
KeFaultDE ENDP
; ---------------------------------------------------------
; General Protection Fault (#13) - Error Code PUSHED
; Stack: [rsp] = ErrCode, [rsp+8] = RIP, [rsp+16] = CS
; General Protection Fault (#13) - error code pushed by CPU
; Exception frame at entry: [rsp]=ErrCode [rsp+8]=RIP [rsp+16]=CS
; ---------------------------------------------------------
KeFaultGP PROC
mov r8, [rsp] ; Arg 3: Error Code
mov rdx, [rsp + 8] ; Arg 2: RIP
mov r8, [rsp] ; Arg3: errCode
mov rdx, [rsp+8] ; Arg2: rip
xor r9, r9 ; Arg4: cr2 = 0 (not a page fault)
mov r10, [rsp+16] ; cs
mov ecx, 13 ; Arg1: vector = 13
; Determine User/Kernel mode from CS
mov rax, [rsp + 16] ; Read CS
and rax, 3
lea r9, StrKernel
lea r10, StrUser
test rax, rax
cmovnz r9, r10 ; Arg 4: Mode String
lea rcx, MsgFaultGP ; Arg 1: Format string
and rsp, -16 ; Align stack
sub rsp, 20h ; 32 bytes shadow space
call KePanic
and rsp, -16
sub rsp, FAULT_FRAME_SIZE
mov [rsp+20h], r10 ; Arg5: cs
call KeFaultDispatch
KeFaultGP ENDP
; ---------------------------------------------------------
; Page Fault (#14) - Error Code PUSHED
; Stack: [rsp] = ErrCode, [rsp+8] = RIP, [rsp+16] = CS
; Page Fault (#14) - error code pushed by CPU
; Exception frame at entry: [rsp]=ErrCode [rsp+8]=RIP [rsp+16]=CS
; ---------------------------------------------------------
KeFaultPF PROC
mov r8, [rsp] ; Arg 3: Error Code
mov rdx, [rsp + 8] ; Arg 2: RIP
mov r9, cr2 ; Arg 4: CR2 (The faulting virtual address)
mov r8, [rsp] ; Arg3: errCode
mov rdx, [rsp+8] ; Arg2: rip
mov r9, cr2 ; Arg4: cr2 (faulting virtual address)
mov r10, [rsp+16] ; cs
mov ecx, 14 ; Arg1: vector = 14
; Determine User/Kernel mode from CS
mov rax, [rsp + 16] ; Read CS
and rax, 3
lea r10, StrKernel
lea r11, StrUser
test rax, rax
cmovnz r10, r11 ; r10 now holds the Mode String
lea rcx, MsgFaultPF ; Arg 1: Format string
; We have 5 arguments for PF! (rcx, rdx, r8, r9, and the stack)
; x64 ABI dictates the 5th argument goes on the stack just above the shadow space.
and rsp, -16 ; Align stack
sub rsp, 30h ; 32 bytes shadow space + 16 bytes for 5th arg and padding
mov [rsp + 20h], r10 ; Arg 5: Mode String (placed exactly after shadow space)
call KePanic
and rsp, -16
sub rsp, FAULT_FRAME_SIZE
mov [rsp+20h], r10 ; Arg5: cs
call KeFaultDispatch
KeFaultPF ENDP
EXTERN KeIrqDispatch:PROC