完成中断管理的基本框架,增加BUILD_ID

This commit is contained in:
pointer-to-bios 2024-03-10 01:27:42 +08:00
parent 38d65b4d70
commit 933eaf3305
21 changed files with 596 additions and 22 deletions

View File

@ -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

View File

@ -0,0 +1,87 @@
#ifndef X86_64_INTERRUPT_PROCS_H
#define X86_64_INTERRUPT_PROCS_H 1
#include <utils.h>
/**
* @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

View File

@ -0,0 +1,25 @@
#ifndef X86_64_PROC_H
#define X86_64_PROC_H 1
#include <types.h>
/**
* @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

View File

@ -1,6 +1,11 @@
#ifndef INTERRUPT_H
#define INTERRUPT_H 1
#ifdef __x86_64__
#include <kernel/arch/x86_64/interrupt.h>
#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

View File

@ -0,0 +1,8 @@
#ifndef INTERRUPT_PROCS
#define INTERRUPT_PROCS 1
#ifdef __x86_64__
#include <kernel/arch/x86_64/interrupt_procs.h>
#endif
#endif

View File

@ -2,13 +2,15 @@
#define KERNEL_H 1
#include <types.h>
#include <kernel/interrupt/procs.h>
#ifdef __x86_64__
#include <kernel/arch/x86_64/kernel.h>
#define ISA_NAME "x86_64"
#endif
#ifndef BUILD_ID
#define BUILD_ID 0
#endif
/**

View File

@ -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

View File

@ -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"

View File

@ -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}
################################

View File

@ -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:

View File

@ -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

View File

@ -0,0 +1,190 @@
#include <kernel/arch/x86_64/interrupt_procs.h>
#include <kernel/arch/x86_64/memm.h>
#include <kernel/arch/x86_64/proc.h>
#include <kernel/kernel.h>
#include <kernel/tty.h>
#include <libk/string.h>
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();
}
}

View File

@ -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

View File

@ -0,0 +1,18 @@
#include <kernel/interrupt.h>
#include <utils.h>
#include <kernel/arch/x86_64/interrupt_procs.h>
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();
}

View File

@ -0,0 +1,11 @@
section .text
global interrupt_open
interrupt_open:
sti
ret
global interrupt_close
interrupt_close:
cli
ret

View File

@ -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

View File

@ -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();

View File

@ -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, "),

View File

@ -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);

View File

@ -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}
################################

11
src/libk/utils.c Normal file
View File

@ -0,0 +1,11 @@
#include <utils.h>
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;
}
}