From 933eaf3305aa937439b500848e3e31cb13b35985 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Sun, 10 Mar 2024 01:27:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=B8=AD=E6=96=AD=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=9A=84=E5=9F=BA=E6=9C=AC=E6=A1=86=E6=9E=B6=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0BUILD=5FID?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel/arch/x86_64/interrupt.h | 25 +++ include/kernel/arch/x86_64/interrupt_procs.h | 87 +++++++++ include/kernel/arch/x86_64/proc.h | 25 +++ include/kernel/interrupt.h | 17 ++ include/kernel/interrupt/procs.h | 8 + include/kernel/kernel.h | 6 +- include/utils.h | 5 + src/Makefile | 7 +- src/kernel/Makefile | 9 +- src/kernel/arch/x86_64/entry32.s | 2 +- src/kernel/arch/x86_64/interrupt.in | 79 ++++++++ src/kernel/arch/x86_64/interrupt_procs.c | 190 +++++++++++++++++++ src/kernel/arch/x86_64/interrupt_procs.s | 97 ++++++++++ src/kernel/arch/x86_64/interrupt_x86_64.c | 18 ++ src/kernel/arch/x86_64/interrupt_x86_64.s | 11 ++ src/kernel/arch/x86_64/kernel.s | 10 - src/kernel/main.c | 4 + src/kernel/main.rs | 1 - src/kernel/memm/allocator/raw.c | 4 +- src/libk/Makefile | 2 +- src/libk/utils.c | 11 ++ 21 files changed, 596 insertions(+), 22 deletions(-) create mode 100644 include/kernel/arch/x86_64/interrupt_procs.h create mode 100644 include/kernel/arch/x86_64/proc.h create mode 100644 include/kernel/interrupt/procs.h create mode 100644 src/kernel/arch/x86_64/interrupt.in create mode 100644 src/kernel/arch/x86_64/interrupt_procs.c create mode 100644 src/kernel/arch/x86_64/interrupt_procs.s create mode 100644 src/kernel/arch/x86_64/interrupt_x86_64.c create mode 100644 src/kernel/arch/x86_64/interrupt_x86_64.s create mode 100644 src/libk/utils.c diff --git a/include/kernel/arch/x86_64/interrupt.h b/include/kernel/arch/x86_64/interrupt.h index 8e2dc9a..1f3cf86 100644 --- a/include/kernel/arch/x86_64/interrupt.h +++ b/include/kernel/arch/x86_64/interrupt.h @@ -41,4 +41,29 @@ typedef struct __gate_descriptor_t */ extern gate_descriptor_t idt[256]; +#define interrupt_gate_generate(desc, addr) \ + { \ + (desc).segment_selector = 0x8; \ + (desc).flags = INTERRUPT_DESCRIPTOR_FLAG_TYPE_INTERRUPT | \ + INTERRUPT_DESCRIPTOR_FLAG_IST; \ + (desc).reserved = 0; \ + (desc).offset_01 = (u16)((u64)(addr)); \ + (desc).offset_23 = (u16)(((u64)(addr)) >> 16); \ + (desc).offset_4567 = (u32)(((u64)(addr)) >> 32); \ + } + +#define trap_gate_generate(desc, addr) \ + { \ + (desc).segment_selector = 0x8; \ + (desc).flags = INTERRUPT_DESCRIPTOR_FLAG_TYPE_TRAP | \ + INTERRUPT_DESCRIPTOR_FLAG_IST; \ + (desc).reserved = 0; \ + (desc).offset_01 = (u16)((u64)(addr)); \ + (desc).offset_23 = (u16)(((u64)(addr)) >> 16); \ + (desc).offset_4567 = (u32)(((u64)(addr)) >> 32); \ + } + +#define interrupt_register_gate(desc, index) \ + idt[index] = desc; + #endif diff --git a/include/kernel/arch/x86_64/interrupt_procs.h b/include/kernel/arch/x86_64/interrupt_procs.h new file mode 100644 index 0000000..cd6d2a0 --- /dev/null +++ b/include/kernel/arch/x86_64/interrupt_procs.h @@ -0,0 +1,87 @@ +#ifndef X86_64_INTERRUPT_PROCS_H +#define X86_64_INTERRUPT_PROCS_H 1 + +#include + +/** + * @name interrupt_entry + * @addindex 平台定制函数 x86_64 + * + * 中断入口程序。 + * + * ```c + * void interrupt_entry(); + * ``` + * + * ```asm + * interrupt_entry_xx: + * ; 保存寄存器上下文 + * interrupt_entry_enter + * + * ; 调用真正的中断处理函数 + * ... + * + * ; 恢复寄存器上下文 + * interrupt_entry_leave + * iret + * ``` + */ +typedef void (*interrupt_entry)(); + +/** + * @name interrupt_entry_gen + * @addindex 平台定制宏 x86_64 + * + * 导入一个中断入口函数声明。 + * + * ```c + * #define interrupt_entry_gen(interrupt) + * ``` + */ +#define interrupt_entry_gen(interrupt) \ + extern void interrupt_entry_##interrupt() +#define interrupt_entry_sym(interrupt) \ + interrupt_entry_##interrupt + +/** + * @name interrupt_request + * @addindex 平台定制函数 + * + * 中断请求处理程序。 + * + * ```c + * void interrupt_request(u64 rip, u64 rsp); + * ``` + * + * 由中断入口程序调用。 + */ +typedef void (*interrupt_request)(u64 rip, u64 rsp, u64 errcode); + +/** + * @name interrupt_req_gen + * @addindex 平台定制宏 x86_64 + * + * 声明一个中断处理函数。 + * + * ```c + * #define interrupt_req_gen(interrupt) + * ``` + */ +#define interrupt_req_gen(interrupt) \ + void interrupt_req_##interrupt(u64 rip, u64 rsp, u64 errcode) +#define interrupt_req_sym(interrupt) \ + interrupt_req_##interrupt + +#define UNSUPPORTED + +#define DE +#define NMI +#define BP + +interrupt_entry_gen(UNSUPPORTED); + +interrupt_entry_gen(DE); +interrupt_entry_gen(NMI); +interrupt_entry_gen(BP); + +#endif diff --git a/include/kernel/arch/x86_64/proc.h b/include/kernel/arch/x86_64/proc.h new file mode 100644 index 0000000..9bf923e --- /dev/null +++ b/include/kernel/arch/x86_64/proc.h @@ -0,0 +1,25 @@ +#ifndef X86_64_PROC_H +#define X86_64_PROC_H 1 + +#include + +/** + * @name proc_texture_registers_t + * @addindex 平台定制宏 x86_64 + * + * 进程上下文的寄存器上下文。 + */ +typedef struct __proc_texture_registers_t +{ + u16 es, ds; + u32 reserved; + u64 r15, r14, r13, r12; + u64 r11, r10, r9, r8; + u64 rdi, rsi, rdx, rbx, rcx, rax; + u64 rbp; + u64 rip, cs; + u64 rflags; + u64 rsp, ss; +} proc_texture_registers_t; + +#endif diff --git a/include/kernel/interrupt.h b/include/kernel/interrupt.h index 4897ea0..a918aa3 100644 --- a/include/kernel/interrupt.h +++ b/include/kernel/interrupt.h @@ -1,6 +1,11 @@ #ifndef INTERRUPT_H #define INTERRUPT_H 1 + +#ifdef __x86_64__ +#include +#endif + /** * @name interrupt_open * @addindex 平台定制函数 @@ -25,4 +30,16 @@ void interrupt_open(); */ void interrupt_close(); +/** + * @name interrupt_init + * @addindex 平台定制函数 + * + * ```c + * void interrupt_init(); + * ``` + * + * 初始化中断功能。 + */ +void interrupt_init(); + #endif diff --git a/include/kernel/interrupt/procs.h b/include/kernel/interrupt/procs.h new file mode 100644 index 0000000..16e9ed0 --- /dev/null +++ b/include/kernel/interrupt/procs.h @@ -0,0 +1,8 @@ +#ifndef INTERRUPT_PROCS +#define INTERRUPT_PROCS 1 + +#ifdef __x86_64__ +#include +#endif + +#endif diff --git a/include/kernel/kernel.h b/include/kernel/kernel.h index 673dd1d..7b4247e 100644 --- a/include/kernel/kernel.h +++ b/include/kernel/kernel.h @@ -2,13 +2,15 @@ #define KERNEL_H 1 #include +#include #ifdef __x86_64__ - #include - #define ISA_NAME "x86_64" +#endif +#ifndef BUILD_ID +#define BUILD_ID 0 #endif /** diff --git a/include/utils.h b/include/utils.h index f312325..5564fa9 100644 --- a/include/utils.h +++ b/include/utils.h @@ -5,4 +5,9 @@ #define DISALIGNED __attribute__((packed)) +#define into_bytes(addr) ((u8 *)(addr)) +#define bytes_into(bytes, type) ((type *)(bytes)) + +void pointer_to_string(u64 addr, char * dest); + #endif diff --git a/src/Makefile b/src/Makefile index 7e15c45..94ca7a6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -14,9 +14,12 @@ endif ALLOCATOR_MAGIC = $(shell "${SOURCE}/magicgen" | sha512sum | head -c 128 | md5sum | head -c 8) +BUILD_ID = $(shell "${SOURCE}/magicgen" | sha512sum | head -c 128 | md5sum | head -c 4) + SUBOBJS = kernel/kernel.o libk/libk.o rust.o -DEFINES = ARCH="${ARCH}" ASM="${ASM}" ASMFLAGS="${ASMFLAGS}" SOURCE="${SOURCE}" PWD="${PWD}" ALLOCATOR_MAGIC="${ALLOCATOR_MAGIC}" +DEFINES = ARCH="${ARCH}" ASM="${ASM}" ASMFLAGS="${ASMFLAGS}" SOURCE="${SOURCE}" PWD="${PWD}" \ + ALLOCATOR_MAGIC="${ALLOCATOR_MAGIC}" BUILD_ID="${BUILD_ID}" ifdef release DEFINES := ${DEFINES} release=1 endif @@ -59,7 +62,7 @@ metaverse.elf: kernel libk rust metaverse.lds all: postproc metaverse.elf @echo -e "Build \e[1;32msucceeded\e[0m." - @echo -e "Build ID \e[1;31m$(shell "${SOURCE}/magicgen"|sha512sum|head -c 128|md5sum|head -c 8)\e[0m." + @echo -e "Build ID \e[1;31m${BUILD_ID}\e[0m." postproc: @echo -n -e "\e[36m" diff --git a/src/kernel/Makefile b/src/kernel/Makefile index 83c5271..7346f5b 100644 --- a/src/kernel/Makefile +++ b/src/kernel/Makefile @@ -7,12 +7,14 @@ CC = gcc CCFLAGS = -m64 -mcmodel=large -I ../../include \ -fno-stack-protector -fno-exceptions \ -fno-builtin -nostdinc -nostdlib \ - -DMEMM_ALLOCATOR_MAGIC="(u32)(0x${ALLOCATOR_MAGIC})" + -DMEMM_ALLOCATOR_MAGIC="(u32)(0x${ALLOCATOR_MAGIC})" \ + -DBUILD_ID="${BUILD_ID}" ifdef release CCFLAGS := ${CCFLAGS} -O2 endif -C_SRCS = main.c tty.c font.c memm.c memm_${ARCH}.c raw.c time.c syscall_${ARCH}.c +C_SRCS = main.c tty.c font.c memm.c memm_${ARCH}.c raw.c time.c syscall_${ARCH}.c interrupt_${ARCH}.c \ + interrupt_procs.c C_OBJS = ${C_SRCS:.c=.c.o} ################################ @@ -27,7 +29,8 @@ endif ASMFLAGS := ${ASMFLAGS} ASMFLAGS32 = -f elf32 -S_SRCS = entry32.s entry.s memm_${ARCH}.s kernel.s syscall_${ARCH}.s +S_SRCS = entry32.s entry.s memm_${ARCH}.s kernel.s syscall_${ARCH}.s interrupt_${ARCH}.s \ + interrupt_procs.s S_OBJS = ${S_SRCS:.s=.s.o} ################################ diff --git a/src/kernel/arch/x86_64/entry32.s b/src/kernel/arch/x86_64/entry32.s index 1dba72f..d6f99f6 100644 --- a/src/kernel/arch/x86_64/entry32.s +++ b/src/kernel/arch/x86_64/entry32.s @@ -105,7 +105,7 @@ gdt: dq 0x0020f80000000000 ; 用户态代码段 dq 0x0000f20000000000 ; 用户态数据段 dq 0 - dq 0x0000891070000000 ; TSS段(低64位) + dq 0x0000891070000068 ; TSS段(低64位) dq 0 ; TSS段(高64位) gdt_end: diff --git a/src/kernel/arch/x86_64/interrupt.in b/src/kernel/arch/x86_64/interrupt.in new file mode 100644 index 0000000..9d9e9bf --- /dev/null +++ b/src/kernel/arch/x86_64/interrupt.in @@ -0,0 +1,79 @@ +%macro store_regs 0 + push rax + push rcx + push rbx + push rdx + push rsi + push rdi + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 +%endmacro + +%macro retrieve_regs 0 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rdi + pop rsi + pop rdx + pop rbx + pop rcx + pop rax +%endmacro + +%macro switch_section 0 + sub rsp, 4 + mov ax, ds + push ax + mov ax, es + push ax + mov ax, 0x10 + mov ds, ax + mov es, ax +%endmacro + +%macro retrieve_section 0 + pop ax + mov es, ax + pop ax + mov ds, ax + add rsp, 4 +%endmacro + +%macro interrupt_entry_enter 0 + push rbp + lea rbp, [rsp] + store_regs + switch_section +%endmacro + +%macro interrupt_entry_leave 0 + retrieve_section + retrieve_regs + leave +%endmacro + +; 用于带有错误码的中断,创建一个没有错误码的上下文拷贝 +%macro interrupt_stack_wrap_texture 0 + extern memcpy + sub rsp, 21 * 8 + mov rdi, rsp + lea rsi, [rsp + 21 * 8] + mov rdx, 16 * 8 + call memcpy + lea rdi, [rsp + 16 * 8] + lea rsi, [rsp + 38 * 8] + mov rdx, 5 * 8 + call memcpy +%endmacro diff --git a/src/kernel/arch/x86_64/interrupt_procs.c b/src/kernel/arch/x86_64/interrupt_procs.c new file mode 100644 index 0000000..92359ac --- /dev/null +++ b/src/kernel/arch/x86_64/interrupt_procs.c @@ -0,0 +1,190 @@ +#include +#include +#include +#include +#include +#include + +interrupt_req_gen(UNSUPPORTED) +{ + tty **tty0_option = tty_get(0); + if (tty0_option == nullptr) + { + KERNEL_TODO(); + } + tty *tty0 = *tty0_option; + tty_text_print(tty0, "Panic: Unsupported interrupt.", RED, BLACK); + KERNEL_TODO(); +} + +static void rip_not_cannonical(u64 rip, tty *tty0) +{ + char num[17]; + memset(num, 0, sizeof(num)); + pointer_to_string(rip, num); + tty_text_print(tty0, "Panic", RED, BLACK); + tty_text_print(tty0, ": Unexpected non-cannonical %rip value ", WHITE, BLACK); + tty_text_print(tty0, num, ORANGE, BLACK); + tty_text_print(tty0, ".\n", WHITE, BLACK); + KERNEL_TODO(); +} + +interrupt_req_gen(DE) +{ + tty **tty0_option = tty_get(0); + if (tty0_option == nullptr) + { + KERNEL_TODO(); + } + tty *tty0 = *tty0_option; + if (!is_cannonical(rip)) + { + rip_not_cannonical(rip, tty0); + } + if (!is_user_address(rip)) + { + char nums[34]; + memset(nums, 0, sizeof(nums)); + pointer_to_string(rip, nums); + pointer_to_string(rsp, nums + 17); + tty_text_print(tty0, "Panic", RED, BLACK); + tty_text_print(tty0, ": Divided by zero occurs in kernel,\n\t", WHITE, BLACK); + tty_text_print(tty0, "with %rip=", WHITE, BLACK); + tty_text_print(tty0, "0x", ORANGE, BLACK); + tty_text_print(tty0, nums, ORANGE, BLACK); + tty_text_print(tty0, ", %rsp=", WHITE, BLACK); + tty_text_print(tty0, "0x", ORANGE, BLACK); + tty_text_print(tty0, nums + 17, ORANGE, BLACK); + tty_text_print(tty0, ".\n", WHITE, BLACK); + KERNEL_TODO(); + } + else + { // TODO 转储并结束进程 + KERNEL_TODO(); + } +} + +interrupt_req_gen(BP) +{ + tty **tty0_option = tty_get(0); + if (tty0_option == nullptr) + { + KERNEL_TODO(); + } + tty *tty0 = *tty0_option; + if (!is_cannonical(rip)) + { + rip_not_cannonical(rip, tty0); + } + proc_texture_registers_t *texture = (void *)errcode; + if (!is_user_address(rip)) + { + char nums[34]; + memset(nums, 0, sizeof(nums)); + pointer_to_string(rip, nums); + pointer_to_string(rsp, nums + 17); + tty_text_print(tty0, "Debug", PURPLE, BLACK); + tty_text_print(tty0, ": Kernel hit a breakpoint,\n\t", WHITE, BLACK); + tty_text_print(tty0, "with %rip=", WHITE, BLACK); + tty_text_print(tty0, "0x", ORANGE, BLACK); + tty_text_print(tty0, nums, ORANGE, BLACK); + tty_text_print(tty0, ", %rsp=", WHITE, BLACK); + tty_text_print(tty0, "0x", ORANGE, BLACK); + tty_text_print(tty0, nums + 17, ORANGE, BLACK); + tty_text_print(tty0, ",\n\t", WHITE, BLACK); + tty_text_print(tty0, "on texture: \n", WHITE, BLACK); + pointer_to_string(texture->rax, nums); + tty_text_print(tty0, "rax\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\t", WHITE, BLACK); + pointer_to_string(texture->rcx, nums); + tty_text_print(tty0, "rcx\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\n", WHITE, BLACK); + pointer_to_string(texture->rbx, nums); + tty_text_print(tty0, "rbx\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\t", WHITE, BLACK); + pointer_to_string(texture->rdx, nums); + tty_text_print(tty0, "rdx\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\n", WHITE, BLACK); + pointer_to_string(texture->rsi, nums); + tty_text_print(tty0, "rsi\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\t", WHITE, BLACK); + pointer_to_string(texture->rdi, nums); + tty_text_print(tty0, "rdi\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\n", WHITE, BLACK); + pointer_to_string(texture->rbp, nums); + tty_text_print(tty0, "rbp\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\t", WHITE, BLACK); + pointer_to_string(texture->rsp, nums); + tty_text_print(tty0, "rsp\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\n", WHITE, BLACK); + pointer_to_string(texture->rip, nums); + tty_text_print(tty0, "rip\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\t", WHITE, BLACK); + pointer_to_string(texture->rflags, nums); + tty_text_print(tty0, "rflags\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\n", WHITE, BLACK); + pointer_to_string(texture->r8, nums); + tty_text_print(tty0, "r8\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\t", WHITE, BLACK); + pointer_to_string(texture->r9, nums); + tty_text_print(tty0, "r9\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\n", WHITE, BLACK); + pointer_to_string(texture->r10, nums); + tty_text_print(tty0, "r10\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\t", WHITE, BLACK); + pointer_to_string(texture->r11, nums); + tty_text_print(tty0, "r11\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\n", WHITE, BLACK); + pointer_to_string(texture->r12, nums); + tty_text_print(tty0, "r12\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\t", WHITE, BLACK); + pointer_to_string(texture->r13, nums); + tty_text_print(tty0, "r13\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\n", WHITE, BLACK); + pointer_to_string(texture->r14, nums); + tty_text_print(tty0, "r14\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\t", WHITE, BLACK); + pointer_to_string(texture->r15, nums); + tty_text_print(tty0, "r15\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\n", WHITE, BLACK); + pointer_to_string(texture->cs, nums); + tty_text_print(tty0, "cs\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\t", WHITE, BLACK); + pointer_to_string(texture->ss, nums); + tty_text_print(tty0, "ss\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\n", WHITE, BLACK); + pointer_to_string(texture->ds, nums); + tty_text_print(tty0, "ds\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\t", WHITE, BLACK); + pointer_to_string(texture->es, nums); + tty_text_print(tty0, "es\t", WHITE, BLACK); + tty_text_print(tty0, nums, BLUE, BLACK); + tty_text_print(tty0, "\n", WHITE, BLACK); + KERNEL_TODO(); + } + else + { // TODO 将当前进程的状态设置为暂停并通知当前进程的调试程序 + KERNEL_TODO(); + } +} diff --git a/src/kernel/arch/x86_64/interrupt_procs.s b/src/kernel/arch/x86_64/interrupt_procs.s new file mode 100644 index 0000000..d83e19e --- /dev/null +++ b/src/kernel/arch/x86_64/interrupt_procs.s @@ -0,0 +1,97 @@ +%include "arch/x86_64/interrupt.in" + +; 栈中的寄存器上下文 +; +------------ +; | ss +; +------------<-- rsp+168(+160) +; | rsp +; +------------<-- rsp+160(+152) +; | rflags +; +------------<-- rsp+152(+144) +; | cs +; +------------<-- rsp+144(+136) +; | rip +; +------------<-- rsp+136(+128) +; | (err code) +; +------------<-- rsp+128 +; | rbp +; +------------<-- rsp+120 +; | rax +; +------------<-- rsp+112 +; | rcx +; +------------<-- rsp+104 +; | rbx +; +------------<-- rsp+96 +; | rdx +; +------------<-- rsp+88 +; | rsi +; +------------<-- rsp+80 +; | rdi +; +------------<-- rsp+72 +; | r8 +; +------------<-- rsp+64 +; | r9 +; +------------<-- rsp+56 +; | r10 +; +------------<-- rsp+48 +; | r11 +; +------------<-- rsp+40 +; | r12 +; +------------<-- rsp+32 +; | r13 +; +------------<-- rsp+24 +; | r14 +; +------------<-- rsp+16 +; | r15 +; +------------<-- rsp+8 +; | reserved +; +------------<-- rsp+4 +; | ds +; +------------<-- rsp+2 +; | es +; +------------<-- rsp+0 + + section .text + + global interrupt_entry_UNSUPPORTED + extern interrupt_req_UNSUPPORTED +interrupt_entry_UNSUPPORTED: + interrupt_entry_enter + + mov rdi, [rsp + 128] + mov rsi, [rsp + 152] + call interrupt_req_UNSUPPORTED + + interrupt_entry_leave + iret + + global interrupt_entry_DE + extern interrupt_req_DE +interrupt_entry_DE: + interrupt_entry_enter + + mov rdi, [rsp + 128] + mov rsi, [rsp + 152] + call interrupt_req_DE + + interrupt_entry_leave + iret + + global interrupt_entry_DE +interrupt_entry_NMI: + ; TODO 暂时不需要为这个中断实现任何功能 + iret + + global interrupt_entry_BP + extern interrupt_req_BP +interrupt_entry_BP: + interrupt_entry_enter + + mov rdi, [rsp + 128] + mov rsi, [rsp + 152] + mov dword [rsp + 4], 0 + mov rdx, rsp + call interrupt_req_BP + + interrupt_entry_leave + iret diff --git a/src/kernel/arch/x86_64/interrupt_x86_64.c b/src/kernel/arch/x86_64/interrupt_x86_64.c new file mode 100644 index 0000000..98f7b00 --- /dev/null +++ b/src/kernel/arch/x86_64/interrupt_x86_64.c @@ -0,0 +1,18 @@ +#include +#include + +#include + +void interrupt_init() +{ + gate_descriptor_t gate; + trap_gate_generate(gate, interrupt_entry_sym(DE)); + interrupt_register_gate(gate, 0); + trap_gate_generate(gate, interrupt_entry_sym(UNSUPPORTED)); + interrupt_register_gate(gate, 1); + trap_gate_generate(gate, interrupt_entry_sym(NMI)); + interrupt_register_gate(gate, 2); + trap_gate_generate(gate, interrupt_entry_sym(BP)); + interrupt_register_gate(gate, 3); + interrupt_open(); +} diff --git a/src/kernel/arch/x86_64/interrupt_x86_64.s b/src/kernel/arch/x86_64/interrupt_x86_64.s new file mode 100644 index 0000000..5ca55b7 --- /dev/null +++ b/src/kernel/arch/x86_64/interrupt_x86_64.s @@ -0,0 +1,11 @@ + section .text + + global interrupt_open +interrupt_open: + sti + ret + + global interrupt_close +interrupt_close: + cli + ret diff --git a/src/kernel/arch/x86_64/kernel.s b/src/kernel/arch/x86_64/kernel.s index 12e8a26..ddb5b2b 100644 --- a/src/kernel/arch/x86_64/kernel.s +++ b/src/kernel/arch/x86_64/kernel.s @@ -19,13 +19,3 @@ prepare_stack: mov rax, [rax] mov [rsp], rax ret - - global interrupt_open -interrupt_open: - sti - ret - - global interrupt_close -interrupt_close: - cli - ret diff --git a/src/kernel/main.c b/src/kernel/main.c index d352580..495e4b2 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -43,6 +43,10 @@ void kmain(void *mb2_bootinfo) get_frame_buffer_with_bootinfo(&fb, &bootinfo); tty *tty0 = tty_new(tty_type_raw_framebuffer, tty_mode_text); tty_set_framebuffer(tty0, &fb); + tty_enable(tty0); + + // 初始化中断管理 + interrupt_init(); // 初始化系统调用 syscall_init(); diff --git a/src/kernel/main.rs b/src/kernel/main.rs index d50d8b1..4bb1227 100644 --- a/src/kernel/main.rs +++ b/src/kernel/main.rs @@ -8,7 +8,6 @@ use super::{ #[no_mangle] extern "C" fn kmain_rust() -> ! { let tty = Tty::from_id(0).unwrap(); - tty.enable(); let mut logger = KernelLogger::new(); logger.info(message!( Msg("Hello, "), diff --git a/src/kernel/memm/allocator/raw.c b/src/kernel/memm/allocator/raw.c index 972c8b2..8080fee 100644 --- a/src/kernel/memm/allocator/raw.c +++ b/src/kernel/memm/allocator/raw.c @@ -72,7 +72,7 @@ void raw_allocator_free(raw_allocator_t *allocator, void *mem) { raw_allocator_cell *cell = allocator->cells; while ((void *)cell < raw_allocator_end(allocator)) - { + { // TODO 内存错误 if (mem == cell->content) { cell->length = 0; @@ -83,7 +83,7 @@ void raw_allocator_free(raw_allocator_t *allocator, void *mem) allocator->rest_memory += cell->capacity + sizeof(raw_allocator_cell); allocator->free_count++; if ( // 可用内存不超过当前allocator的 5% 或调用free次数很多时 - allocator->size / allocator->rest_memory > 20 && + allocator->size / allocator->rest_memory > 20 || allocator->free_count > RAW_ALLOCATOR_FREE_MAX) { raw_allocator_cellmerge(allocator); diff --git a/src/libk/Makefile b/src/libk/Makefile index 6f49226..56776b3 100644 --- a/src/libk/Makefile +++ b/src/libk/Makefile @@ -11,7 +11,7 @@ ifdef release CCFLAGS := ${CCFLAGS} -O2 endif -C_SRCS = bootinfo.c lst.c +C_SRCS = bootinfo.c lst.c utils.c C_OBJS = ${C_SRCS:.c=.c.o} ################################ diff --git a/src/libk/utils.c b/src/libk/utils.c new file mode 100644 index 0000000..8e986f9 --- /dev/null +++ b/src/libk/utils.c @@ -0,0 +1,11 @@ +#include + +void pointer_to_string(u64 addr, char *dest) +{ + for (u8 i = 0; i < 16; i++) + { + char c = addr & 0xf; + dest[15 - i] = (c < 10) ? c + '0' : c - 10 + 'a'; + addr >>= 4; + } +}