0xF0000000 - 0xFFFFFFFF: kernel memory (~ 256 MB)
0xC0000000 - 0xF0000000: mixed ring 0 drivers/servers (768 MB)
0x00000000 - 0XC0000000: process memory (3 GB)
Drvers and servers are stored in recloatable elf format
Shared memory with drivers/servers:
If sharing memory with a ring 3 driver/server, use page tables to map parts of both of the address spaces of each process to the same physical memory location
If sharing memory with a ring 0 driver/server, simply edit the processes memory directly
Drivers/servers do not need to be recompiled to be in either ring 0 or ring 3
interface directly to kernel:
- thru sysenter, or call gate, or interrupt (whichever is the fastest available)
sysenter:
-- Target code segment - read from SYSTENTER_CS_MSR
-- Target instruction - read from SYSENTER_EIP_MSR
-- Stack segment - SYSENTER_CS_MSR + 8
-- Stack pointer - SYSENTER_ESP_MSR
sysexit:
-- Target code segment - SYSENTER_CS_MSR + 16
-- Target instruction - EDX
-- Stack segment - SYSENTER_CS_MSR + 24
-- Stack pointer - ECX
sysenter calling method:
push arg3
push arg2
push arg1
call call_system ; Standard C calling convention
add esp, 12
call_system: ; int call_system(int function_number, arguments, ...)
mov ecx, esp
sysenter
state in kernel after sysenter:
CS:EIP = SYSENTER_CS_MSR:SYSENTER_EIP_MSR
SS:ESP = SYSENTER_CS_MSR+8:SYSENTER_ESP_MSR
ECX = pointer to process stack
[ECX] = Return address
[ECX+4] = First argument (function number)
sysenter_entry: ; In kernel
; Stuff to jump to function based on [ecx+4]
; ecx = pointer to process stack
; eax = return value
mov edx, [ecx]
sub ecx, 4
sysexit