增加systemcall支持,添加x86_64中断的基本数据结构
This commit is contained in:
parent
57aaf60af5
commit
13d76c4e6a
|
@ -0,0 +1,26 @@
|
|||
#ifndef X86_64_INTERRUPT_H
|
||||
#define X86_64_INTERRUPT_H 1
|
||||
|
||||
#include <types.h>
|
||||
|
||||
typedef struct __gate_descriptor_t
|
||||
{
|
||||
u16 offset_01;
|
||||
u16 segment_selector; // for code segment
|
||||
u16 flags;
|
||||
u16 offset_23;
|
||||
u32 offset_4567;
|
||||
u32 reserved;
|
||||
} gate_descriptor_t;
|
||||
|
||||
// interrupt stack table,每个表项都指向tss
|
||||
// 需要加载寄存器IA32_INTERRUPT_SSP_TABLE
|
||||
#define INTERRUPT_DESCRIPTOR_FLAG_IST(ssp) (ssp)
|
||||
|
||||
// 在第15位上有一个表示代码段是否存在的标志位,代码段总是存在,故直接设置为1
|
||||
#define INTERRUPT_DESCRIPTOR_FLAG_TYPE_INTERRUPT (0x8e << 8)
|
||||
#define INTERRUPT_DESCRIPTOR_FLAG_TYPE_TRAP (0x8f << 8)
|
||||
|
||||
extern gate_descriptor_t idt[256];
|
||||
|
||||
#endif
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef X86_64_SYSCALL
|
||||
#define X86_64_SYSCALL 1
|
||||
|
||||
#include <types.h>
|
||||
|
||||
extern void *system_calls_table[256];
|
||||
|
||||
// 系统调用使用的寄存器:
|
||||
// rax - 调用号
|
||||
// rbx - 系统调用程序保留
|
||||
// rcx - rip寄存器缓存
|
||||
// rdi - 系统调用程序保留
|
||||
// rdx - 参数1
|
||||
// r8 - 参数2
|
||||
// r9 - 参数3
|
||||
// r10 - 参数4
|
||||
// r11 - rflags寄存器缓存
|
||||
// r12 - 参数5
|
||||
// r13 - 参数6
|
||||
// r14 - 参数7
|
||||
// r15 - 参数8
|
||||
|
||||
// 系统调用时,使用内核主堆栈
|
||||
// 故设置一组函数,用于在sysret前保存和在syscall后加载
|
||||
// rbp, rsp的函数
|
||||
extern void save_kernel_stack();
|
||||
extern void load_kernel_stack();
|
||||
|
||||
extern void set_kernel_stack_cache(usize stack);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef INTERRUPT_H
|
||||
#define INTERRUPT_H 1
|
||||
|
||||
void interrupt_open();
|
||||
void interrupt_close();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef SYSCALL_H
|
||||
#define SYSCALL_H 1
|
||||
|
||||
#ifdef __x86_64__
|
||||
#include <kernel/arch/x86_64/syscall.h>
|
||||
#endif
|
||||
|
||||
void syscall_init();
|
||||
|
||||
#endif
|
|
@ -11,7 +11,7 @@ ifdef release
|
|||
CCFLAGS := ${CCFLAGS} -O2
|
||||
endif
|
||||
|
||||
C_SRCS = main.c tty.c font.c memm.c memm_${ARCH}.c raw.c time.c
|
||||
C_SRCS = main.c tty.c font.c memm.c memm_${ARCH}.c raw.c time.c syscall_${ARCH}.c
|
||||
C_OBJS = ${C_SRCS:.c=.c.o}
|
||||
|
||||
################################
|
||||
|
@ -26,7 +26,7 @@ endif
|
|||
ASMFLAGS := ${ASMFLAGS}
|
||||
ASMFLAGS32 = -f elf32
|
||||
|
||||
S_SRCS = entry32.s entry.s memm_${ARCH}.s kernel.s
|
||||
S_SRCS = entry32.s entry.s memm_${ARCH}.s kernel.s syscall_${ARCH}.s
|
||||
S_OBJS = ${S_SRCS:.s=.s.o}
|
||||
|
||||
################################
|
||||
|
|
|
@ -1,13 +1,31 @@
|
|||
section .entry align=8
|
||||
extern kmain
|
||||
extern systemcall_procedure
|
||||
global init64
|
||||
init64:
|
||||
endbr64
|
||||
cli
|
||||
|
||||
; 加载段寄存器
|
||||
mov rax, 0x1000000
|
||||
mov rbp, rax
|
||||
mov rsp, rax
|
||||
mov rdi, rbx
|
||||
|
||||
; 加载系统调用相关寄存器
|
||||
; IA32_STAR = 0x0018_0008_0000_0000
|
||||
mov rcx, 0xc0000081
|
||||
mov rax, 0x0018000800000000
|
||||
wrmsr
|
||||
; IA32_FMASK = 0xffff_ffff
|
||||
inc rcx
|
||||
mov rax, 0xffffffff
|
||||
wrmsr
|
||||
; IA32_LSTAR = [systemcall_procedure]
|
||||
lea rcx, [rcx + 2]
|
||||
lea rax, [systemcall_procedure]
|
||||
wrmsr
|
||||
|
||||
jmp kmain
|
||||
|
||||
section .multiboot2 align=8
|
||||
|
|
|
@ -37,6 +37,13 @@ init32:
|
|||
add edi, 4
|
||||
loop init32_loop0
|
||||
|
||||
; 设置idt_ptr
|
||||
mov eax, 0x10403a ; idt_ptr + 2
|
||||
mov dword [eax], 0x104050
|
||||
; 加载IDTR寄存器
|
||||
db 0x66
|
||||
lidt [0x104038]
|
||||
|
||||
; 设置gdt_ptr
|
||||
mov eax, 0x10402a ; gdt_ptr + 2
|
||||
mov dword [eax], 0x104000 ; gdt
|
||||
|
@ -98,6 +105,18 @@ gdt:
|
|||
dq 0x0000f20000000000 ; 用户态数据段
|
||||
gdt_end:
|
||||
|
||||
gdt_ptr:
|
||||
gdt_ptr: ; 0x104028
|
||||
dw gdt_end - gdt - 1
|
||||
dq gdt
|
||||
|
||||
resb 6
|
||||
|
||||
idt_ptr: ; 0x104038
|
||||
dw 0x7ff
|
||||
dq idt
|
||||
|
||||
resb 14
|
||||
|
||||
global idt
|
||||
idt:
|
||||
resq 512 ; 16 bytes per descriptor (512 q-bytes)
|
||||
|
|
|
@ -19,3 +19,13 @@ prepare_stack:
|
|||
mov rax, [rax]
|
||||
mov [rsp], rax
|
||||
ret
|
||||
|
||||
global interrupt_open
|
||||
interrupt_open:
|
||||
sti
|
||||
ret
|
||||
|
||||
global interrupt_close
|
||||
interrupt_close:
|
||||
cli
|
||||
ret
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#include <kernel/syscall.h>
|
||||
|
||||
#include <libk/string.h>
|
||||
|
||||
void syscall_init()
|
||||
{
|
||||
memset(&system_calls_table, 0, sizeof(system_calls_table));
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
section .data
|
||||
global system_calls_table
|
||||
system_calls_table:
|
||||
resq 256
|
||||
|
||||
kernel_stack_cache:
|
||||
dq 0, 0 ; 分别为 rbp, rsp
|
||||
|
||||
section .text
|
||||
global systemcall_procedure
|
||||
global save_kernel_stack
|
||||
systemcall_procedure:
|
||||
endbr64
|
||||
call load_kernel_stack
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
|
||||
shl rax, 3 ; rax *= 8
|
||||
; 将对应调用号的系统调用加载至rax
|
||||
lea rdi, [system_calls_table]
|
||||
lea rax, [rax + rdi]
|
||||
; 判断是否为空调用
|
||||
cmp rax, 0
|
||||
je systemcall_procedure_none_call
|
||||
mov rax, [rax]
|
||||
; 调用对应的系统调用
|
||||
call rax
|
||||
|
||||
leave
|
||||
call save_kernel_stack
|
||||
sysret
|
||||
|
||||
systemcall_procedure_none_call:
|
||||
; TODO 调用了不存在的系统调用,属于无法恢复的错误,应保存错误状态并结束调用进程
|
||||
; 暂时直接sysret
|
||||
leave
|
||||
call save_kernel_stack
|
||||
sysret
|
||||
|
||||
; void set_kernel_stack_cache(usize stack)
|
||||
set_kernel_stack_cache:
|
||||
endbr64
|
||||
push rax
|
||||
|
||||
lea rax, [kernel_stack_cache]
|
||||
mov [rax], rdi
|
||||
lea rax, [rax + 8]
|
||||
mov [rax], rdi
|
||||
|
||||
pop rax
|
||||
ret
|
||||
|
||||
save_kernel_stack:
|
||||
endbr64
|
||||
lea rbx, [kernel_stack_cache]
|
||||
; 交换[rbx]与rbp
|
||||
mov rdi, [rbx]
|
||||
xor rbp, rdi
|
||||
xor rdi, rbp
|
||||
xor rbp, rdi
|
||||
mov [rbx], rdi
|
||||
lea rbx, [rbx + 8]
|
||||
; 交换[rbx]与rsp
|
||||
mov rdi, [rbx]
|
||||
xor rsp, rdi
|
||||
xor rdi, rsp
|
||||
xor rsp, rdi
|
||||
mov [rbx], rdi
|
||||
ret
|
||||
|
||||
load_kernel_stack:
|
||||
endbr64
|
||||
lea rbx, [kernel_stack_cache]
|
||||
; 交换[rbx]与rbp
|
||||
mov rdi, [rbx]
|
||||
xor rbp, rdi
|
||||
xor rdi, rbp
|
||||
xor rbp, rdi
|
||||
mov [rbx], rdi
|
||||
lea rbx, [rbx + 8]
|
||||
; 交换[rbx]与rsp
|
||||
mov rdi, [rbx]
|
||||
xor rsp, rdi
|
||||
xor rdi, rsp
|
||||
xor rsp, rdi
|
||||
mov [rbx], rdi
|
||||
ret
|
|
@ -1,6 +1,8 @@
|
|||
#include <kernel/kernel.h>
|
||||
#include <kernel/tty.h>
|
||||
#include <kernel/memm.h>
|
||||
#include <kernel/interrupt.h>
|
||||
#include <kernel/syscall.h>
|
||||
|
||||
#include <libk/multiboot2.h>
|
||||
#include <libk/math.h>
|
||||
|
@ -42,6 +44,9 @@ void kmain(void *mb2_bootinfo)
|
|||
tty *tty0 = tty_new(tty_type_raw_framebuffer, tty_mode_text);
|
||||
tty_set_framebuffer(tty0, &fb);
|
||||
|
||||
// 初始化系统调用
|
||||
syscall_init();
|
||||
|
||||
// 为rust准备正确对齐的栈
|
||||
prepare_stack();
|
||||
|
||||
|
|
Reference in New Issue