1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
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
|