My code that switches to user mode:
Code: Select all
mov ax,0x23
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov rdi, user
mov rsi, rsp
mov dx, 0x1b
mov ax, 0x23
push rax
push rsi
push 0x200
push rdx
push rdi
iret
user:
mov rcx, target_read + 0x1000
mov rax, [rcx]
jmp $
target_read:
dd 0xdeadbeaf
dd 0xdeadbeaf
Code: Select all
let mut gdt = GlobalDescriptorTable::new();
let code_selector = gdt.add_entry(Descriptor::kernel_code_segment()); // 0x08
let data_selector = gdt.add_entry(Descriptor::kernel_data_segment()); // 0x10
let usercode = gdt.add_entry(Descriptor::user_code_segment()); // 0x18
let userdata = gdt.add_entry(Descriptor::user_data_segment()); // 0x20
let tss_selector = gdt.add_entry(Descriptor::tss_segment(&TSS)); // 0x28
(gdt, Selectors { code_selector, tss_selector, data_selector, usercode, userdata })
The exact instruvtion failing is the iret, with the old code and stack segments, and CPU flags set to 0x10006. It is failing with a General Protection Fault, error code 32768.