bits 64 global load_gdt_and_idt global start_user_mode section .rodata ;0x28 picked to align with limine choice ;0x28 - kernel code ;0x30 - kernel data ;0x38 - user data ;0x40 - user code gdtr: dw 0x47 dq gdt gdt: dq 0 dq 0 dq 0 dq 0 dq 0 dq 0x00209b0000000000 dq 0x00009b0000000000 dq 0x0000fb0000000000 dq 0x0020fb0000000000 idtr: dw 4095 dq idt idt: times 256 - ($ - idt) / 16 dq 0 section .text load_gdt_and_idt: lgdt [gdtr] lidt [idtr] ret extern syscall_encode_color encode_color_syscall: call syscall_encode_color mov edi, eax xor rax, rax mov eax, edi xor rdi, rdi xor rsi, rsi xor rdx, rdx jmp syscall_return extern syscall_get_fb_vaddr extern syscall_get_fb_dims extern syscall_get_fb_pitch get_framebuffer_syscall: call syscall_get_fb_vaddr push rax call syscall_get_fb_dims push rax call syscall_get_fb_pitch xor rsi, rsi mov esi, eax pop rdi pop rax xor rdx, rdx jmp syscall_return extern syscall_copy_framebuffer draw_framebuffer_syscall: call syscall_copy_framebuffer xor rax, rax xor rdi, rdi xor rsi, rsi xor rdx, rdx jmp syscall_return bad_syscall: xor rax, rax xor rdi, rdi xor rsi, rsi xor rdx, rdx jmp syscall_return syscall_entry: mov r11, rsp mov rsp, 0xfffffffffffff000 push r11 push rcx cmp rax, 0 je encode_color_syscall cmp rax, 1 je get_framebuffer_syscall cmp rax, 2 je draw_framebuffer_syscall jmp bad_syscall syscall_return: xor r8, r8 xor r9, r9 xor r10, r10 xor r11, r11 or r11, 0x200 pop rcx pop rsp o64 sysret start_user_mode: ;intended rip in rdi ;intended rsp in rsi ;intended p4_paddr in rdx mov rax, rdx mov cr3, rax ;efer <- efer | 0x1 mov rcx, 0xc0000080 rdmsr or al, 1 wrmsr ;lstar <- syscall_entry mov rdx, syscall_entry mov eax, edx shr rdx, 32 mov ecx, 0xc0000082 wrmsr ;star <- 0x0030.0028.0000.0000 mov edx, 0x00300028 xor eax, eax mov ecx, 0xc0000081 wrmsr mov rcx, rdi mov rsp, rsi xor r11, r11 or r11, 0x200 xor rax, rax xor rbx, rbx xor rdx, rdx xor rdi, rdi xor rsi, rsi xor rbp, rbp xor r8, r8 xor r9, r9 xor r10, r10 xor r12, r12 xor r13, r13 xor r14, r14 xor r15, r15 o64 sysret