From 57aaf60af5fc29e0a542b61b2e32c0c902ffd2cd Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Mon, 5 Feb 2024 23:50:36 +0800 Subject: [PATCH 01/37] =?UTF-8?q?=E6=8F=90=E4=BE=9Bvscode=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 - .vscode/c_cpp_properties.json | 16 ++++++++++++++++ .vscode/settings.json | 9 +++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 .vscode/c_cpp_properties.json create mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index d907548..6cd1797 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -/.vscode /test/metaverse.img *.o *.map diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..fe4e235 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,16 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/include" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "c17", + "intelliSenseMode": "linux-gcc-x64", + "configurationProvider": "ms-vscode.makefile-tools" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6970732 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "C_Cpp.errorSquiggles": "disabled", + "files.associations": { + "*.s": "nasm", + "LICENCE": "plaintext", + "*.h": "c" + }, + "rust-analyzer.imports.preferNoStd" : true, +} \ No newline at end of file From 13d76c4e6afd95f54156a0a7dc1cab03d380b47e Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Tue, 6 Feb 2024 21:10:51 +0800 Subject: [PATCH 02/37] =?UTF-8?q?=E5=A2=9E=E5=8A=A0systemcall=E6=94=AF?= =?UTF-8?q?=E6=8C=81=EF=BC=8C=E6=B7=BB=E5=8A=A0x86=5F64=E4=B8=AD=E6=96=AD?= =?UTF-8?q?=E7=9A=84=E5=9F=BA=E6=9C=AC=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel/arch/x86_64/interrupt.h | 26 ++++++++ include/kernel/arch/x86_64/syscall.h | 31 +++++++++ include/kernel/interrupt.h | 7 ++ include/kernel/syscall.h | 10 +++ src/kernel/Makefile | 4 +- src/kernel/arch/x86_64/entry.s | 18 +++++ src/kernel/arch/x86_64/entry32.s | 21 +++++- src/kernel/arch/x86_64/kernel.s | 10 +++ src/kernel/arch/x86_64/syscall_x86_64.c | 8 +++ src/kernel/arch/x86_64/syscall_x86_64.s | 87 +++++++++++++++++++++++++ src/kernel/main.c | 5 ++ 11 files changed, 224 insertions(+), 3 deletions(-) create mode 100644 include/kernel/arch/x86_64/interrupt.h create mode 100644 include/kernel/arch/x86_64/syscall.h create mode 100644 include/kernel/interrupt.h create mode 100644 include/kernel/syscall.h create mode 100644 src/kernel/arch/x86_64/syscall_x86_64.c create mode 100644 src/kernel/arch/x86_64/syscall_x86_64.s diff --git a/include/kernel/arch/x86_64/interrupt.h b/include/kernel/arch/x86_64/interrupt.h new file mode 100644 index 0000000..e4110a2 --- /dev/null +++ b/include/kernel/arch/x86_64/interrupt.h @@ -0,0 +1,26 @@ +#ifndef X86_64_INTERRUPT_H +#define X86_64_INTERRUPT_H 1 + +#include + +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 diff --git a/include/kernel/arch/x86_64/syscall.h b/include/kernel/arch/x86_64/syscall.h new file mode 100644 index 0000000..3ed2abf --- /dev/null +++ b/include/kernel/arch/x86_64/syscall.h @@ -0,0 +1,31 @@ +#ifndef X86_64_SYSCALL +#define X86_64_SYSCALL 1 + +#include + +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 diff --git a/include/kernel/interrupt.h b/include/kernel/interrupt.h new file mode 100644 index 0000000..b2f703b --- /dev/null +++ b/include/kernel/interrupt.h @@ -0,0 +1,7 @@ +#ifndef INTERRUPT_H +#define INTERRUPT_H 1 + +void interrupt_open(); +void interrupt_close(); + +#endif diff --git a/include/kernel/syscall.h b/include/kernel/syscall.h new file mode 100644 index 0000000..1c9507a --- /dev/null +++ b/include/kernel/syscall.h @@ -0,0 +1,10 @@ +#ifndef SYSCALL_H +#define SYSCALL_H 1 + +#ifdef __x86_64__ +#include +#endif + +void syscall_init(); + +#endif diff --git a/src/kernel/Makefile b/src/kernel/Makefile index 093fa03..f47b005 100644 --- a/src/kernel/Makefile +++ b/src/kernel/Makefile @@ -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} ################################ diff --git a/src/kernel/arch/x86_64/entry.s b/src/kernel/arch/x86_64/entry.s index 04f86fd..efbb1ad 100644 --- a/src/kernel/arch/x86_64/entry.s +++ b/src/kernel/arch/x86_64/entry.s @@ -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 diff --git a/src/kernel/arch/x86_64/entry32.s b/src/kernel/arch/x86_64/entry32.s index 57d618b..f68326e 100644 --- a/src/kernel/arch/x86_64/entry32.s +++ b/src/kernel/arch/x86_64/entry32.s @@ -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) diff --git a/src/kernel/arch/x86_64/kernel.s b/src/kernel/arch/x86_64/kernel.s index ddb5b2b..12e8a26 100644 --- a/src/kernel/arch/x86_64/kernel.s +++ b/src/kernel/arch/x86_64/kernel.s @@ -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 diff --git a/src/kernel/arch/x86_64/syscall_x86_64.c b/src/kernel/arch/x86_64/syscall_x86_64.c new file mode 100644 index 0000000..0d2ea49 --- /dev/null +++ b/src/kernel/arch/x86_64/syscall_x86_64.c @@ -0,0 +1,8 @@ +#include + +#include + +void syscall_init() +{ + memset(&system_calls_table, 0, sizeof(system_calls_table)); +} diff --git a/src/kernel/arch/x86_64/syscall_x86_64.s b/src/kernel/arch/x86_64/syscall_x86_64.s new file mode 100644 index 0000000..8b9ae7a --- /dev/null +++ b/src/kernel/arch/x86_64/syscall_x86_64.s @@ -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 diff --git a/src/kernel/main.c b/src/kernel/main.c index 70f8871..06be3cb 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include #include @@ -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(); From d14187ea96c5fffe96d317b91279d25547eec582 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Mon, 12 Feb 2024 02:59:33 +0800 Subject: [PATCH 03/37] =?UTF-8?q?=E8=A7=84=E8=8C=83=E7=AC=A6=E5=8F=B7?= =?UTF-8?q?=E5=91=BD=E5=90=8D=EF=BC=8C=E5=90=8C=E6=AD=A5=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E7=9A=84=E6=8F=8F=E8=BF=B0=EF=BC=8C=E7=A7=BB=E9=99=A4=E4=B8=8D?= =?UTF-8?q?=E5=BF=85=E8=A6=81=E7=9A=84=E5=AE=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel/arch/x86_64/interrupt.h | 3 ++- include/kernel/arch/x86_64/memm.h | 2 +- include/libk/lst.h | 2 +- include/utils.h | 8 -------- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/include/kernel/arch/x86_64/interrupt.h b/include/kernel/arch/x86_64/interrupt.h index e4110a2..fb6b536 100644 --- a/include/kernel/arch/x86_64/interrupt.h +++ b/include/kernel/arch/x86_64/interrupt.h @@ -2,6 +2,7 @@ #define X86_64_INTERRUPT_H 1 #include +#include typedef struct __gate_descriptor_t { @@ -11,7 +12,7 @@ typedef struct __gate_descriptor_t u16 offset_23; u32 offset_4567; u32 reserved; -} gate_descriptor_t; +} DISALIGNED gate_descriptor_t; // interrupt stack table,每个表项都指向tss // 需要加载寄存器IA32_INTERRUPT_SSP_TABLE diff --git a/include/kernel/arch/x86_64/memm.h b/include/kernel/arch/x86_64/memm.h index a8594ee..65401f0 100644 --- a/include/kernel/arch/x86_64/memm.h +++ b/include/kernel/arch/x86_64/memm.h @@ -15,7 +15,7 @@ typedef enum __memm_page_size extern u64 PML4[512]; -#define MEMM_PAGE_TABLE_FLAGS_AREA ((u64)0xfff) +#define MEMM_PAGE_TABLE_FLAGS_MASK ((u64)0xfff) /* 页对齐掩码 */ #define MEMM_4K_ALIGN_MASK ((u64)0xfff) diff --git a/include/libk/lst.h b/include/libk/lst.h index 4cc7e4d..205217c 100644 --- a/include/libk/lst.h +++ b/include/libk/lst.h @@ -33,7 +33,7 @@ bool lst_remove(lst_iterator_t *lst, usize left, usize right, bool force); /* 在`lst`中添加一个线段[left,right) force=true时忽略已经存在于`lst`中的线段 -force=false时若有存在于`lst`中的线段,只添加这些部分之外的线段,返回false,否则返回true +force=false时若有存在于`lst`中的线段,不添加任何线段,返回false,否则返回true */ bool lst_add(lst_iterator_t *lst, usize left, usize right, bool force); diff --git a/include/utils.h b/include/utils.h index 4050e10..f312325 100644 --- a/include/utils.h +++ b/include/utils.h @@ -3,14 +3,6 @@ #include -#define UTILS_BIT_GET(byte, bit) ((byte) & (1 << (bit))) -#define UTILS_BIT_SET(byte, bit) ((byte) |= (1 << (bit))); -#define UTILS_BIT_RESET(byte, bit) ((byte) &= ~(1 << (bit))); - -#define UTILS_BITMAP_GET(map, bit) (((u8 *)(map))[bit / 8] & (1 << ((bit) % 8))) -#define UTILS_BITMAP_SET(map, bit) (((u8 *)(map))[bit / 8] |= (1 << ((bit) % 8))); -#define UTILS_BITMAP_RESET(map, bit) (((u8 *)(map))[bit / 8] &= ~(1 << ((bit) % 8))); - #define DISALIGNED __attribute__((packed)) #endif From 7e22dd604f2eec2e102ffc1f82b76485bc1f4c6d Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Tue, 13 Feb 2024 01:01:59 +0800 Subject: [PATCH 04/37] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=88=86=E9=85=8D?= =?UTF-8?q?=E5=99=A8allocate=E5=87=BD=E6=95=B0=E4=B8=8D=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E7=9A=84align=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel/memm.h | 2 +- src/kernel/memm/allocator/raw.c | 2 +- src/kernel/memm/memm.c | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/kernel/memm.h b/include/kernel/memm.h index f4714ae..8c40127 100644 --- a/include/kernel/memm.h +++ b/include/kernel/memm.h @@ -23,7 +23,7 @@ /* 只分配不映射空间 */ #define MEMM_ALLOC_ONLY_MEMORY (128 * 1024 * 1024) -typedef void *(*memm_allocate_t)(void *allocator, usize size, usize align); +typedef void *(*memm_allocate_t)(void *allocator, usize size); typedef void (*memm_free_t)(void *allocator, void *mem); /* diff --git a/src/kernel/memm/allocator/raw.c b/src/kernel/memm/allocator/raw.c index ce158de..972c8b2 100644 --- a/src/kernel/memm/allocator/raw.c +++ b/src/kernel/memm/allocator/raw.c @@ -13,7 +13,7 @@ void raw_allocator_new(raw_allocator_t *allocator, usize size) allocator->cells[0].length = 0; } -void *raw_allocator_allocate(raw_allocator_t *allocator, usize size, usize align) +void *raw_allocator_allocate(raw_allocator_t *allocator, usize size) { usize real_size = size; align_to(real_size, 16); diff --git a/src/kernel/memm/memm.c b/src/kernel/memm/memm.c index 787befa..db66100 100644 --- a/src/kernel/memm/memm.c +++ b/src/kernel/memm/memm.c @@ -24,7 +24,7 @@ mem_manager_t *memm_new(usize mem_size) MEMM_RAW_ALLOCATOR, 0); allocator_iterator_t *alcatr_ind = allocator0->allocate( - &allocator0->allocator_instance, sizeof(allocator_iterator_t), 0); + &allocator0->allocator_instance, sizeof(allocator_iterator_t)); alcatr_ind->allocator = allocator0; alcatr_ind->left = nullptr; @@ -37,7 +37,7 @@ mem_manager_t *memm_new(usize mem_size) align_to(pmc_size, 8); pmc_size /= 8; - memory_manager.page_map = allocator0->allocate(&allocator0->allocator_instance, pmc_size, 0); + memory_manager.page_map = allocator0->allocate(&allocator0->allocator_instance, pmc_size); memset(memory_manager.page_map, 0, pmc_size); memset(memory_manager.page_map, 0xff, MEMM_ALLOC_ONLY_MEMORY / MEMM_PAGE_SIZE / 8); for (usize i = (MEMM_ALLOC_ONLY_MEMORY / MEMM_PAGE_SIZE / 8) * (u8)8; @@ -48,7 +48,7 @@ mem_manager_t *memm_new(usize mem_size) // 配置分配器页地图 memory_manager.map_with_allocator = - allocator0->allocate(&allocator0->allocator_instance, pmc_size, 0); + allocator0->allocate(&allocator0->allocator_instance, pmc_size); memset(memory_manager.map_with_allocator, 0, pmc_size); for (usize i = kernel_initial_size / MEMM_PAGE_SIZE; i < MEMM_ALLOC_ONLY_MEMORY / MEMM_PAGE_SIZE; @@ -59,7 +59,7 @@ mem_manager_t *memm_new(usize mem_size) // 分配器释放页地图 memory_manager.map_with_destructed_allocator = - allocator0->allocate(&allocator0->allocator_instance, pmc_size, 0); + allocator0->allocate(&allocator0->allocator_instance, pmc_size); memset(memory_manager.map_with_destructed_allocator, 0, pmc_size); // 配置空闲页线段搜索表 @@ -103,14 +103,14 @@ void *memm_find_and_allocate(allocator_iterator_t *allocator_ind, usize size, us allocator_t *allocator = allocator_ind->allocator; if (allocator->pid == pid && allocator->full == false) { // 尝试用本节点分配 - if ((ptr = allocator->allocate(&allocator->allocator_instance, size, 0)) != nullptr) + if ((ptr = allocator->allocate(&allocator->allocator_instance, size)) != nullptr) { *writeback = allocator; return ptr; } else { - if ((ptr = allocator->allocate(&allocator->allocator_instance, 0, 0)) == nullptr) + if ((ptr = allocator->allocate(&allocator->allocator_instance, 0)) == nullptr) allocator->full = true; } } @@ -197,7 +197,7 @@ void *memm_allocate(usize size, usize pid) allind->left = nullptr; allind->right = nullptr; insert_allocator(memory_manager.allocators, allind); - ptr = new_allocator->allocate(&new_allocator->allocator_instance, orgsize, 0); + ptr = new_allocator->allocate(&new_allocator->allocator_instance, orgsize); after_allocation: if (ptr != nullptr) From 197c50ff5dc5c11638bb18f402d437c77333c043 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Tue, 13 Feb 2024 02:01:23 +0800 Subject: [PATCH 05/37] =?UTF-8?q?=E7=BB=99allocator=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E9=AD=94=E6=95=B0=EF=BC=8C=E7=94=A8=E4=BA=8E=E5=9C=A8=E8=B0=83?= =?UTF-8?q?=E7=94=A8free=E6=97=B6=E7=A1=AE=E8=AE=A4=E5=86=85=E5=AD=98?= =?UTF-8?q?=E6=89=80=E5=B1=9Eallocator=E6=98=AF=E5=90=A6=E6=98=AF=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E6=9C=89=E6=95=88=E7=9A=84allocator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel/memm.h | 5 +++-- include/kernel/memm/allocator/raw.h | 2 +- src/kernel/memm/memm.c | 3 +++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/kernel/memm.h b/include/kernel/memm.h index 8c40127..432c72c 100644 --- a/include/kernel/memm.h +++ b/include/kernel/memm.h @@ -32,6 +32,9 @@ typedef void (*memm_free_t)(void *allocator, void *mem); */ typedef struct __allocator_t { + #define MEMM_ALLOCATOR_MAGIC_NUM 0x271fe441 + u32 magic; + bool initialized; // 在本分配器中调用allocate返回nullptr后为true @@ -47,7 +50,6 @@ typedef struct __allocator_t // 分配器实例的allocate函数 // 无法分配空间返回nullptr // 在size参数为0时,保证不可以分配空间,但是如果空间已满依然返回nullptr - // 当参数align=0时表示不需要对齐 memm_allocate_t allocate; // 分配器实例的free函数 @@ -129,7 +131,6 @@ void memm_allocator_destruct(allocator_t *allocator); /* 申请内存 -第三个参数也是返回值,表示申请内存使用的分配器 pid=0时为内核分配 所有内存在内核空间都有对物理内存空间的直接映射,也就是线性地址与物理地址相同,称为内核地址 diff --git a/include/kernel/memm/allocator/raw.h b/include/kernel/memm/allocator/raw.h index 96fbe90..9dc1784 100644 --- a/include/kernel/memm/allocator/raw.h +++ b/include/kernel/memm/allocator/raw.h @@ -36,7 +36,7 @@ typedef struct __raw_allocator_t void raw_allocator_new(raw_allocator_t *allocator, usize size); -void *raw_allocator_allocate(raw_allocator_t *allocator, usize size, usize align); +void *raw_allocator_allocate(raw_allocator_t *allocator, usize size); void raw_allocator_free(raw_allocator_t *allocator, void *mem); #endif diff --git a/src/kernel/memm/memm.c b/src/kernel/memm/memm.c index db66100..9afab18 100644 --- a/src/kernel/memm/memm.c +++ b/src/kernel/memm/memm.c @@ -72,6 +72,7 @@ mem_manager_t *memm_new(usize mem_size) allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid) { allocator_t *allocator = start; + allocator->magic = MEMM_ALLOCATOR_MAGIC_NUM; allocator->initialized = true; allocator->full = false; allocator->pid = 0; @@ -220,6 +221,8 @@ void *memm_user_allocate(usize size, usize pid) void memm_free(void *mem) { allocator_t *allocator = memm_addr_get_allocator(mem); + if (allocator->magic != MEMM_ALLOCATOR_MAGIC_NUM) + return; if (is_user_address((u64)mem)) { // TODO 对于用户空间的地址需要先转换到内核地址后释放 } From 073e50029a054131bfb75df092798752e268d225 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Sun, 18 Feb 2024 02:29:40 +0800 Subject: [PATCH 06/37] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=86=85=E5=AD=98?= =?UTF-8?q?=E9=A1=B5=E8=AE=A1=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kernel/arch/x86_64/memm_x86_64.c | 15 ++++++++++++++- src/kernel/main.c | 2 +- src/kernel/memm/memm.c | 21 +++++++++++++-------- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/kernel/arch/x86_64/memm_x86_64.c b/src/kernel/arch/x86_64/memm_x86_64.c index cd86dba..080de11 100644 --- a/src/kernel/arch/x86_64/memm_x86_64.c +++ b/src/kernel/arch/x86_64/memm_x86_64.c @@ -110,7 +110,6 @@ bool memm_map_pageframes_to( return false; while (size != 0) { - // 这是当前需要映射的页的内存对齐(或者说是当前映射的页的大小) memm_page_size align = memm_get_page_align(physical); if (align == MEMM_PAGE_SIZE_1G) { @@ -123,6 +122,20 @@ bool memm_map_pageframes_to( align = MEMM_4K_ALIGN_MASK + 1; } align /= MEMM_PAGE_SIZE; + memory_manager_t *mm = memm_get_manager(); + switch (align) + { + case MEMM_PAGE_SIZE_4K: + mm->mapped_4k_page++; + case MEMM_PAGE_SIZE_2M: + mm->mapped_2m_page++; + case MEMM_PAGE_SIZE_1G: + mm->mapped_1g_page++; + } + for (usize i = physical / MEMM_PAGE_SIZE; i < physical / MEMM_PAGE_SIZE + align; i++) + { + bitmap_set(mm->page_map, i); + } map_pageframe_to(target, physical, user, write, align); diff --git a/src/kernel/main.c b/src/kernel/main.c index 06be3cb..d352580 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -35,7 +35,7 @@ void kmain(void *mb2_bootinfo) } // 初始化内存管理模块 - mem_manager_t *memm = memm_new(mem_size); + memory_manager_t *memm = memm_new(mem_size); // 初始化tty模块 tty_controller_t *tty_controler = tty_controller_new(); diff --git a/src/kernel/memm/memm.c b/src/kernel/memm/memm.c index 9afab18..f2cbf71 100644 --- a/src/kernel/memm/memm.c +++ b/src/kernel/memm/memm.c @@ -5,9 +5,9 @@ #include #include -mem_manager_t memory_manager; +memory_manager_t memory_manager; -mem_manager_t *memm_new(usize mem_size) +memory_manager_t *memm_new(usize mem_size) { memset(&memory_manager, 0, sizeof(memory_manager)); memory_manager.memory_size = mem_size; @@ -47,20 +47,20 @@ mem_manager_t *memm_new(usize mem_size) } // 配置分配器页地图 - memory_manager.map_with_allocator = + memory_manager.allocator_map = allocator0->allocate(&allocator0->allocator_instance, pmc_size); - memset(memory_manager.map_with_allocator, 0, pmc_size); + memset(memory_manager.allocator_map, 0, pmc_size); for (usize i = kernel_initial_size / MEMM_PAGE_SIZE; i < MEMM_ALLOC_ONLY_MEMORY / MEMM_PAGE_SIZE; i += MEMM_PAGE_SIZE) { - bitmap_set(memory_manager.map_with_allocator, i); + bitmap_set(memory_manager.allocator_map, i); } // 分配器释放页地图 - memory_manager.map_with_destructed_allocator = + memory_manager.destructed_allocator_map = allocator0->allocate(&allocator0->allocator_instance, pmc_size); - memset(memory_manager.map_with_destructed_allocator, 0, pmc_size); + memset(memory_manager.destructed_allocator_map, 0, pmc_size); // 配置空闲页线段搜索表 memory_manager.available_pages_table = lst_new(0, memory_manager.page_amount); @@ -69,6 +69,11 @@ mem_manager_t *memm_new(usize mem_size) return &memory_manager; } +memory_manager_t *memm_get_manager() +{ + return &memory_manager; +} + allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid) { allocator_t *allocator = start; @@ -177,7 +182,7 @@ void *memm_allocate(usize size, usize pid) return nullptr; // 内存中已经没有可分配的页了 for (usize i = allocator_start; i < allocator_start + size; i++) { - bitmap_set(memory_manager.map_with_allocator, i); + bitmap_set(memory_manager.allocator_map, i); } memm_map_pageframes_to( allocator_start * MEMM_PAGE_SIZE, allocator_start * MEMM_PAGE_SIZE, From 71f2aa6616f61d1e00dc0ca51c3f442f5751dbad Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Sun, 18 Feb 2024 02:31:16 +0800 Subject: [PATCH 07/37] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E4=B8=8D=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E7=9A=84klog.h=20C=E8=AF=AD=E8=A8=80=E5=A4=B4?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel/klog.h | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 include/kernel/klog.h diff --git a/include/kernel/klog.h b/include/kernel/klog.h deleted file mode 100644 index 7415cc0..0000000 --- a/include/kernel/klog.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef KLOG_H -#define KLOG_H 1 - -#include - -#define KLOG_BUFFER_SIZE 2 * 1024 * 1024 - -typedef struct __klogger -{ - usize tty; - char buffer[KLOG_BUFFER_SIZE]; - usize index; -} klogger; - -#endif From 5bd549328fe1721eeb79773705666953970e94cb Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Sun, 18 Feb 2024 03:53:54 +0800 Subject: [PATCH 08/37] =?UTF-8?q?=E5=A2=9E=E5=8A=A0c=E8=AF=AD=E8=A8=80?= =?UTF-8?q?=E9=83=A8=E5=88=86=E7=9A=84=E6=96=87=E6=A1=A3=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=EF=BC=8C=E6=AD=A3=E5=9C=A8=E5=BC=80=E5=8F=91=E7=9A=84=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E7=94=9F=E6=88=90=E5=99=A8=E5=B0=86=E4=BC=9A=E4=BB=8E?= =?UTF-8?q?=E6=BA=90=E4=BB=A3=E7=A0=81=E7=9A=84=E6=96=87=E6=A1=A3=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=E7=94=9F=E6=88=90markdown=E6=A0=BC=E5=BC=8F=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +- docs/contribution.md | 13 ++ include/kernel/arch/x86_64/interrupt.h | 21 +- include/kernel/arch/x86_64/kernel.h | 10 +- include/kernel/arch/x86_64/memm.h | 177 +++++++++++++-- include/kernel/arch/x86_64/syscall.h | 63 +++-- include/kernel/clock/time.h | 33 +++ include/kernel/interrupt.h | 21 ++ include/kernel/kernel.h | 36 ++- include/kernel/memm.h | 303 +++++++++++++++++++------ include/kernel/memm/allocator/raw.h | 27 +++ include/kernel/syscall.h | 9 + 12 files changed, 610 insertions(+), 117 deletions(-) create mode 100644 docs/contribution.md diff --git a/README.md b/README.md index 4600d15..d8f2512 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,8 @@ make debug * [x] raw_allocator * [x] tty * [x] 内核日志 +* [ ] 系统调用 +* [ ] 中断管理 * [ ] 文件系统 * [ ] vfs * [ ] fat32驱动(移植) @@ -64,9 +66,19 @@ make debug * [ ] 驱动管理 * [ ] 进程管理 +## 文档 + +* 从源代码注释生成文档 + +```bash +make doc +``` + +(开发中) + ## 作出贡献 -通过向此仓库发送PR为我们作出贡献。 +通过向此仓库发送PR为我们作出贡献,详见[contribution.md](docs/contribution.md)。 ## 版权声明 diff --git a/docs/contribution.md b/docs/contribution.md new file mode 100644 index 0000000..622a26b --- /dev/null +++ b/docs/contribution.md @@ -0,0 +1,13 @@ +# 向Metaverse内核贡献代码 + +通过如下方式向内核增加你的代码: + +* 从[github仓库](https://github.com/metaverse-kernel/kernel-dev)或[Random World Studio内部仓库](http://git.suthby.org:2024/metaverse/kernel-dev)创建一个分支 +* 在你的分支中增加代码 +* 测试你增加的代码的正确性,并尽量确保对原有代码没有影响 +* 无需在注释中加入代码更改日志,git可以做到 +* 在文档的适当的位置增加对新特性的描述 +* 完成编码和文档的工作后向主仓库发送PR +* 等待审核代码 + +若你的代码通过审核,将会把你的PR合并到主分支中。 diff --git a/include/kernel/arch/x86_64/interrupt.h b/include/kernel/arch/x86_64/interrupt.h index fb6b536..04c9dfd 100644 --- a/include/kernel/arch/x86_64/interrupt.h +++ b/include/kernel/arch/x86_64/interrupt.h @@ -4,6 +4,12 @@ #include #include +/** + * @name gate_descriptor_t + * @addindex 平台依赖结构 x86_64 + * + * 门描述符的结构体形式。 + */ typedef struct __gate_descriptor_t { u16 offset_01; @@ -14,14 +20,25 @@ typedef struct __gate_descriptor_t u32 reserved; } DISALIGNED gate_descriptor_t; -// interrupt stack table,每个表项都指向tss -// 需要加载寄存器IA32_INTERRUPT_SSP_TABLE +/** + * @name INTERRUPT_DESCRIPTOR_FLAG_IST + * @addindex 平台依赖结构 x86_64 + * + * `gate_descriptor_t`的`flags`的标志位。 + * + * `ssp`代表一个tss描述符在任务段中的的索引。 + */ #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) +/** + * @name idt + * + * 中断描述符表。 + */ extern gate_descriptor_t idt[256]; #endif diff --git a/include/kernel/arch/x86_64/kernel.h b/include/kernel/arch/x86_64/kernel.h index 65462a5..5ac5529 100644 --- a/include/kernel/arch/x86_64/kernel.h +++ b/include/kernel/arch/x86_64/kernel.h @@ -3,7 +3,13 @@ #include -// 具有返回值是为了留出一个寄存器用于调整栈顶 -extern usize prepare_stack(); +/** + * @name prepare_stack + * + * ```c + * void prepare_stack(); + * ``` + */ +extern void prepare_stack(); #endif diff --git a/include/kernel/arch/x86_64/memm.h b/include/kernel/arch/x86_64/memm.h index 65401f0..2702399 100644 --- a/include/kernel/arch/x86_64/memm.h +++ b/include/kernel/arch/x86_64/memm.h @@ -4,8 +4,18 @@ #include #include -/* 页大小,以MEMM_PAGE_SIZE为单位 */ +/** + * @name MEMM_PAGE_SIZE + * @addindex 平台定制宏 + * + * 最小的页大小。 + * + * @if arch == x86_64 then + * 4096 + * @endif + */ #define MEMM_PAGE_SIZE 4096 + typedef enum __memm_page_size { MEMM_PAGE_SIZE_4K = 1, // 1个4KB页大小 @@ -15,14 +25,49 @@ typedef enum __memm_page_size extern u64 PML4[512]; +/** + * @name MEMM_PAGE_TABLE_FLAGS_MASK + * @addindex 平台依赖宏 x86_64 + * + * 页表项中属性标志位使用的最低12位的掩码`0xfff`。 + */ #define MEMM_PAGE_TABLE_FLAGS_MASK ((u64)0xfff) -/* 页对齐掩码 */ +/** + * @name MEMM_xx_ALIGN_MASK + * @addindex 平台依赖宏 x86_64 + * + * 页对齐掩码。 + * `xx`为`x86_64`架构的页的三种大小,分别为`4K`、`2M`和`1G`。这些页一定是以它们自己的大小对齐,因此会出现低n位总为0的情况。 + * `4K`对应`0xfff`;`2M`对应`0x1fffff`;`1G`对应`0x3fffffff`。 + */ #define MEMM_4K_ALIGN_MASK ((u64)0xfff) #define MEMM_2M_ALIGN_MASK ((u64)0x1fffff) #define MEMM_1G_ALIGN_MASK ((u64)0x3fffffff) -/* 页表项属性FLAGS */ +/** + * @name MEMM_ENTRY_FLAG_xx + * @addindex 平台依赖宏 x86_64 + * + * 页表项属性标志位。定义如下: + * + * ```c + * #define MEMM_ENTRY_FLAG_PRESENT ((u64)1) + * #define MEMM_ENTRY_FLAG_WRITE ((u64)1 << 1) + * #define MEMM_ENTRY_FLAG_USER ((u64)1 << 2) + * #define MEMM_ENTRY_FLAG_PWT ((u64)1 << 3) + * #define MEMM_ENTRY_FLAG_PCD ((u64)1 << 4) + * #define MEMM_ENTRY_FLAG_ACCECED ((u64)1 << 5) + * #define MEMM_ENTRY_FLAG_DIRTY ((u64)1 << 6) + * #define MEMM_ENTRY_FLAG_PS ((u64)1 << 7) + * #define MEMM_ENTRY_FLAG_GLOBAL ((u64)1 << 8) + * #define MEMM_ENTRY_FLAG_PAT ((u64)1 << 12) + * #define MEMM_PTE_ENTRY_FLAG_PAT ((u64)1 << 7) + * #define MEMM_ENTRY_FLAG_XD ((u64)1 << 63) + * ``` + * + * 其中`MEMM_PTE_ENTRY_FLAG_PAT`的`pte`表示此属性标志位只存在与`pte`页表项中。 + */ #define MEMM_ENTRY_FLAG_PRESENT ((u64)1) #define MEMM_ENTRY_FLAG_WRITE ((u64)1 << 1) #define MEMM_ENTRY_FLAG_USER ((u64)1 << 2) @@ -35,18 +80,47 @@ extern u64 PML4[512]; #define MEMM_ENTRY_FLAG_PAT ((u64)1 << 12) #define MEMM_PTE_ENTRY_FLAG_PAT ((u64)1 << 7) #define MEMM_ENTRY_FLAG_XD ((u64)1 << 63) + +/** + * @name memm_entry_flag_get(entry, flag) + * @addindex 平台依赖宏 x86_64 + * + * 获取页表项中某个属性标志位,得到布尔值。 + * + * 其中`flag`是`MEMM_ENTRY_FLAG_xx`。 + */ #define memm_entry_flag_get(entry, flag) \ ((entry & flag) ? true : false) -/* 页表(大型页)项地址域掩码 */ +/** + * @name MEMM_ENTRY_ADDRESS_MASK, MEMM_BP_ENTRY_ADDRESS_MASK + * @addindex 平台依赖宏 x86_64 + * + * 页表项地址域掩码。将页表项与掩码作与运算可得到页表项指向的**下一级页表的起始地址**或**页框的起始地址**。 + * + * 含`BP`的为大型页页表项的地址域掩码。 + * + * 定义如下: + * + * ```c + * #define MEMM_ENTRY_ADDRESS_MASK ((u64)0x000ffffffffff000) + * #define MEMM_BP_ENTRY_ADDRESS_MASK ((u64)0x000fffffffffe000) + * ``` + */ #define MEMM_ENTRY_ADDRESS_MASK ((u64)0x000ffffffffff000) #define MEMM_BP_ENTRY_ADDRESS_MASK ((u64)0x000fffffffffe000) + +/** + * @name memm_entry_get_address(entry) + * @addindex 平台依赖宏 x86_64 + * + * 获取页表项指向的地址。 + */ #define memm_entry_get_address(entry) \ ((entry) & (memm_entry_flag_get(entry, MEMM_ENTRY_FLAG_PS) \ ? MEMM_BP_ENTRY_ADDRESS_MASK \ : MEMM_ENTRY_ADDRESS_MASK)) -/* 线性地址表项索引或页内偏移掩码 */ #define MEMM_LA_PML4EI_MASK ((u64)0x0000ff8000000000) #define MEMM_LA_PDPTEI_MASK ((u64)0x0000007fc0000000) #define MEMM_LA_PDEI_MASK ((u64)0x000000003fe00000) @@ -56,50 +130,119 @@ extern u64 PML4[512]; #define MEMM_LA_2MB_PAGE_OFFSET_MASK ((u64)0x00000000001fffff) #define MEMM_LA_4KB_PAGE_OFFSET_MASK ((u64)0x0000000000000fff) -/* 线性地址表项索引偏移位数 */ #define MEMM_LA_PML4EI_OFFSET (39) #define MEMM_LA_PDPTEI_OFFSET (30) #define MEMM_LA_PDEI_OFFSET (21) #define MEMM_LA_PEI_OFFSET (12) -/* 获取线性地址中某个表项索引以及获取页内偏移 */ +/** + * @name MEMM_LA_xxxxI + * @addindex 平台依赖宏 x86_64 + * + * 在4级分页中,线性地址的四个页表项索引宏。其中`xxxx`分别为`PML4E`、`PDPTE`、`PDE`和`PE`。 + */ #define MEMM_LA_PML4EI #define MEMM_LA_PDPTEI #define MEMM_LA_PDEI #define MEMM_LA_PEI + +/** + * @name memm_la_get_entry_index(addr, entry) + * @addindex 平台依赖宏 x86_64 + * + * 获取线性地址`addr`中的`entry`页表项索引。 + * + * 其中`entry`应为宏`MEMM_LA_xxxxI`。 + */ #define memm_la_get_entry_index(addr, entry) \ (((addr) & (entry##_MASK)) >> (entry##_OFFSET)) +/** + * @name MEMM_LA_xxx_PAGE_OFFSET + * @addindex 平台依赖宏 x86_64 + * + * 线性地址的页内偏移宏。其中`xxx`为三种页容量`4KB`、`2MB`、`1GB`。 + */ #define MEMM_LA_1GB_PAGE_OFFSET #define MEMM_LA_2MB_PAGE_OFFSET #define MEMM_LA_4KB_PAGE_OFFSET + +/** + * @name memm_la_get_offset(addr, page_type) + * @addindex 平台依赖宏 x86_64 + * + * 获取线性地址的页内偏移部分。 + * + * 其中`page_type`应为宏`MEMM_LA_xxx_PAGE_OFFSET`。 + */ #define memm_la_get_offset(addr, page_type) \ ((addr) & (page_type##_MASK)) -/* -仅支持canonical型地址 - -target与physical至少都是以MEMM_PAGE_SIZE对齐的 - -没有MEMM_PAGE_SIZE对齐的,和非canonical型地址都会返回false - -当剩余长度超过1GB的一半且地址1GB对齐,则会映射一个1GB页; -当剩余长度超过2MB的一半且地址2MB对齐,则会映射一个2MB页; -否则映射4KB页。 +/** + * @name memm_map_pageframes_to + * + * ```c + * bool memm_map_pageframes_to( + * u64 target, u64 physical, + * usize size, + * bool user, bool write); + * ``` + * + * 仅支持**canonical**型地址 + * + * `target`与`physical`保证至少都是以MEMM_PAGE_SIZE对齐的。 + * + * 没有MEMM_PAGE_SIZE对齐的,和非canonical型地址都会返回false + * + * 当剩余长度超过1GB的一半且地址1GB对齐,则会映射一个1GB页; + * 当剩余长度超过2MB的一半且地址2MB对齐,则会映射一个2MB页; + * 否则映射4KB页。 */ bool memm_map_pageframes_to( u64 target, u64 physical, usize size, bool user, bool write); +/** + * @name reload_pml4 + * @addindex 平台依赖宏 x86_64 + * + * ```c + * void reload_pml4(); + * ``` + */ extern void reload_pml4(); +/** + * @name is_user_address(addr) + * @addindex 平台定制宏 + * + * 判断`addr`是否是一个用户空间地址,得到一个布尔值。 + * + * @if arch == x86_64 + * `canonical`型地址的高地址为用户空间,低地址为内核空间。 + * @endif + */ #define is_user_address(addr) \ (((addr) > 0xffff7fffffffffff) ? true : false) +/** + * @name is_cannonical(addr) + * @addindex 平台依赖宏 x86_64 + * + * 判断`addr`是否是一个cannonical型地址。 + */ #define is_cannonical(addr) \ (((addr) < 0x0000800000000000 || (addr) > 0xffff7fffffffffff) ? true : false) +/** + * @name memm_get_page_align(addr) + * @addindex 平台依赖宏 x86_64 + * + * 获取地址`addr`的页对齐大小,得到一个`memm_page_size`类型值。 + * + * 当地址`addr`是*4KB对齐*或*没有4KB对齐时*,都得到`MEMM_PAGE_SIZE_4K`。 + */ #define memm_get_page_align(addr) \ (is_aligned(addr, MEMM_PAGE_SIZE_1G) \ ? MEMM_PAGE_SIZE_1G \ diff --git a/include/kernel/arch/x86_64/syscall.h b/include/kernel/arch/x86_64/syscall.h index 3ed2abf..71f4e5c 100644 --- a/include/kernel/arch/x86_64/syscall.h +++ b/include/kernel/arch/x86_64/syscall.h @@ -5,27 +5,50 @@ 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(); +/** + * @brief 系统调用规范 + * @addindex x86_64 + * + * 系统调用使用的寄存器: + * rax - 调用号 + * rbx - 系统调用程序保留 + * rcx - rip寄存器缓存 + * rdi - 系统调用程序保留 + * rdx - 参数1 + * r8 - 参数2 + * r9 - 参数3 + * r10 - 参数4 + * r11 - rflags寄存器缓存 + * r12 - 参数5 + * r13 - 参数6 + * r14 - 参数7 + * r15 - 参数8 + * + * 系统调用时,使用内核主堆栈。 + */ +/** + * @name set_kernel_stack_cache + * @addindex 平台依赖函数 x86_64 + * + * ```c + * void set_kernel_stack_cache(usize stack); + * ``` + * + * 将堆栈缓存设为一个`stack`。 + */ extern void set_kernel_stack_cache(usize stack); +/** + * @name return_from_systemcall + * @addindex 平台依赖函数 x86_64 + * + * ```c + * void return_from_systemcall(); + * ``` + * + * 执行`sysret`指令。 + */ +extern void return_from_systemcall(); + #endif diff --git a/include/kernel/clock/time.h b/include/kernel/clock/time.h index b6cb4de..b680658 100644 --- a/include/kernel/clock/time.h +++ b/include/kernel/clock/time.h @@ -4,12 +4,45 @@ #include // 使用UNIX时间戳 +/** + * @name system_time_get + * + * ```c + * usize system_time_get(); + * ``` + * + * 系统时间。 + * + * 系统时间使用精确到毫秒的unix时间,即值`0`代表1970-1-1 00:00:00的第一毫秒前。 + */ usize system_time_get(); // 如果硬件支持更高的计时精度, // 此函数提供从系统unix时间开始到现在的纳秒为单位的时间 +/** + * @name system_time_ns_get + * + * ```c + * usize system_time_ns_get(); + * ``` + * + * 纳秒级系统时间。 + * + * 如果硬件支持更高的计时精度,此函数返回以纳秒为单位的时间。但不表明硬件必须支持纳秒级的计时。 + * + * 即使硬件支持更高的计时精度,内核也会根据情况自主选择是否使用更高的精度计时。 + */ usize system_time_ns_get(); +/** + * @name system_time_increase + * + * ```c + * void system_time_increase(); + * ``` + * + * 将毫秒级系统时间增加。 + */ void system_time_increase(); #endif diff --git a/include/kernel/interrupt.h b/include/kernel/interrupt.h index b2f703b..4897ea0 100644 --- a/include/kernel/interrupt.h +++ b/include/kernel/interrupt.h @@ -1,7 +1,28 @@ #ifndef INTERRUPT_H #define INTERRUPT_H 1 +/** + * @name interrupt_open + * @addindex 平台定制函数 + * + * ```c + * void interrupt_open(); + * ``` + * + * 开启中断 + */ void interrupt_open(); + +/** + * @name interrupt_close + * @addindex 平台定制函数 + * + * ```c + * void interrupt_close(); + * ``` + * + * 开启中断 + */ void interrupt_close(); #endif diff --git a/include/kernel/kernel.h b/include/kernel/kernel.h index 7d84b16..673dd1d 100644 --- a/include/kernel/kernel.h +++ b/include/kernel/kernel.h @@ -11,11 +11,33 @@ #endif +/** + * @name KERNEL_TODO + * + * 表示此处还没有实现代码。 + */ #define KERNEL_TODO() \ while (true) \ { \ } +/** + * @name simple_lock + * + * 简易同步锁。有如下两个方法: + * + * ```c + * #define simple_lock_lock(lock) + * ``` + * + * 获取一个锁。 + * + * ```c + * #define simple_lock_unlock(lock) + * ``` + * + * 解开一个锁。 + */ #define simple_lock_lock(lock) \ { \ while (lock == true) \ @@ -24,8 +46,20 @@ } #define simple_lock_unlock(lock) (lock) = false; +/** + * @name kmain_rust + * + * rust内核主程序。 + */ extern void kmain_rust(); -extern void *kend; // 内核结束的标记 +/** + * @name kend + * + * 内核结束的标记。 + * + * 此变量不代表任何值,但是此变量的地址被安排到了内核镜像的末尾,用于标志内核结束的位置。 + */ +extern void *kend; #endif diff --git a/include/kernel/memm.h b/include/kernel/memm.h index 432c72c..0074ca8 100644 --- a/include/kernel/memm.h +++ b/include/kernel/memm.h @@ -8,57 +8,127 @@ #include /** - * @brief 内存管理模块 + * @name MEMM_MAX_SUPPORTED_MEMORY * - * TODO 还没设计页回收算法 + * 支持的最大物理内存,为固定值`1TB`。 */ - -/* 最大支持1TB内存 */ #define MEMM_MAX_SUPPORTED_MEMORY (1024 * (1024 * (1024 * (usize)1024))) -/* 最大支持的分页数量 */ -// 这里的页均以最小的页大小计算 +/** + * @name MEMM_MAX_SUPPORTED_PAGES + * + * 支持的最大页数量,通过宏`MEMM_MAX_SUPPORTED_MEMORY`与宏`MEMM_PAGE_SIZE`相除得到。 + */ #define MEMM_MAX_SUPPORTED_PAGES (MEMM_MAX_SUPPORTED_MEMORY / MEMM_PAGE_SIZE) -/* 只分配不映射空间 */ +/** + * @name MEMM_ALLOC_ONLY_MEMORY + * + * 只分配不映射空间,暂时为固定值`128MB`。物理地址`0`\~`MEMM_ALLOC_ONLY_MEMORY`的空间在进入内核前已经映射至内核空间。 + * + * 这段内存空间包含**1MB以内低地址**、**内核镜像**以及未分配空间,未分配空间被一个分配器独占。 + */ #define MEMM_ALLOC_ONLY_MEMORY (128 * 1024 * 1024) +/** + * @name memm_allocate_t, memm_free_t + * + * 分配器的一对`分配`、`释放`函数指针。内核中可以根据情况使用多种不同的分配器来分配内存,`allocator`中提供一对此类型的变量,用于 + * 动态绑定不同的分配器。 + * + * 分配器在`kernel/memm/allocator/`中定义。 + * + * 分配器**必须**实现的行为: + * + * **`memm_allocate_t`**: + * + * ```c + * typedef void *(*memm_allocate_t)(void *allocator, usize size); + * ``` + * + * 从分配器`allocator`中分配`size`字节的内存。 + * + * 无法分配空间时返回`nullptr`;当参数`size`为0时,需要检查分配器占有的空间的可用性,无可用空间时需要返回`nullptr`; + * **返回的地址的16字节前**必须保留8字节空间用于存放内存所在分配器的内核空间地址。 + * + * **`memm_free_t`**: + * + * ```c + * typedef void (*memm_free_t)(void *allocator, void *mem); + * ``` + * + * 释放分配器`allocator`中的内存`mem`。 + * + * 由于此函数只由内核调用,因此对参数作出保证,保证地址`mem`属于这个`allocator`。 + */ typedef void *(*memm_allocate_t)(void *allocator, usize size); typedef void (*memm_free_t)(void *allocator, void *mem); -/* -内存分配器 -分配器对象的首地址永远是MEMM_PAGE_SIZE对齐的 +/** + * @name allocator_t + * + * ```c + * typedef struct { } allocator_t; + * ``` + * + * 内存分配器。 + * + * 内存分配器用于为`memm_allocate`函数提供管理数据以及分配空间。 + * + * 在**内核镜像结尾**至`MEMM_ALLOC_ONLY_MEMORY`空间中,包含一个分配器`内核大分配器`。 + * + * 分配器指针**必须**使用内核地址。 + * + * @internal full + * + * 调用分配器的`allocate`方法后,在返回`nullptr`时会设为`true`。 + * 调用分配器的`free`方法时设为`false`。 + * + * @internal pid + * + * 进程标志服,表示此分配器所属的进程,为0代表属于内核。 + * + * @internal type + * + * 分配器类型。在目录`include/kernel/memm/allocator`中对每个分配器分别定义一个唯一值。 + * + * @internal allocate + * + * 分配器实例的allocate函数。当无法分配空间时返回nullptr。在size参数为0时,保证不可以分配空间, + * 但是如果空间已满依然返回nullptr。 + * + * @internal free + * + * 分配器实例的free函数。若不是allocate得到的地址则什么都不做。 + * + * @internal allocator_instance + * + * 分配器实例。 */ typedef struct __allocator_t { - #define MEMM_ALLOCATOR_MAGIC_NUM 0x271fe441 +#define MEMM_ALLOCATOR_MAGIC_NUM 0x271fe441 u32 magic; bool initialized; - // 在本分配器中调用allocate返回nullptr后为true - // 调用free后为false + // 调用分配器的`allocate`方法后,在返回`nullptr`时会设为`true`。 + // 调用分配器的`free`方法时设为`false`。 bool full; - // 进程id,当pid=0时代表内核 + // 进程标志服,表示此分配器所属的进程,为0代表属于内核。 usize pid; - // 分配器类型 + // 分配器类型。在目录`include/kernel/memm/allocator`中对每个分配器分别定义一个唯一值。 usize type; usize size; - // 分配器实例的allocate函数 - // 无法分配空间返回nullptr - // 在size参数为0时,保证不可以分配空间,但是如果空间已满依然返回nullptr + // 分配器实例的allocate函数。当无法分配空间时返回nullptr。在size参数为0时, + // 保证不可以分配空间,但是如果空间已满依然返回nullptr。 memm_allocate_t allocate; - - // 分配器实例的free函数 - // 若不是allocate得到的地址则什么都不做 + // 分配器实例的free函数。若不是allocate得到的地址则什么都不做。 memm_free_t free; - // 分配器实例 - // 对应`type`类型使用 - // 在kernel/memm/allocator/中是所有的内存分配器 + // 分配器实例。 u64 allocator_instance[0]; } allocator_t; @@ -68,93 +138,178 @@ typedef struct __allocator_iterator_t struct __allocator_iterator_t *left, *right; } allocator_iterator_t; -/* -内存管理器 -内存分配分成两个阶段:映射和分配 -映射后的页进入allocator记录中,具体的分配工作由allocator完成 - -在page_map中置位、在map_with_allocator中复位、在map_with_destructed_allocator中复位 -且不在available_pages_table中的页,是页表、程序代码段、内核代码等使用的页 -*/ +/** + * @name 内存管理器 + * + * @internal alloc_only_memory + * + * 在进入内核主程序之前,有些不在内核中的虚拟内存空间已经被页表映射,这部分内存不可以再映射到物理页框。 + * + * @internal mapped_page_amount + * + * 已经映射的页数量。若不是最小的页会被视作多个最小页计数。 + * + * @internal mapped_4k_page, mapped_2m_page, mapped_1g_page + * @addindex 平台依赖宏 x86_64 + * + * 分别记录已经映射的三种大小页的数量。 + * + * @internal page_map + * + * 页地图,每个bit表示对应的最小页是否被映射。 + * + * @internal allocator_map + * + * 分配器地图。每个bit表示对应的最小页是否被一个分配器控制。 + * + * @internal destructed_allocator_map + * + * 释放的分配器页地图。每个bit表示对应的最小页是否曾经被分配器控制并且现在控制这个页的分配器已经释放。 + * + * 值为1的bit位对应的最小页可以直接**取消映射**、**重新构造一个分配器**、**加载可执行程序**等。 + * + * @internal available_pages_table + * + * 空闲页线段搜索表。 + * + * @internal allocators + * + * 分配器二叉树。 + */ typedef struct __mem_manager_t { usize memory_size; usize page_amount; - // 这里记录的数量为最小的页的数量 - usize mapped_page_amount; - - // 在进入内核主程序之前,有些不在内核中的虚拟内存空间已经被 - // 页表映射,这部分内存不可以再映射到物理页框 + // 在进入内核主程序之前,有些不在内核中的虚拟内存空间已经被页表映射,这部分内存不可以再映射到物理页框 usize alloc_only_memory; + + // 已经映射的页数量。若不是最小的页会被视作多个最小页计数。 + usize mapped_page_amount; #ifdef __x86_64__ - // 在这里三种页的数量分别记录 usize mapped_4k_page; usize mapped_2m_page; usize mapped_1g_page; #endif - // 页地图 - // 每个bit都表示这个页是否被映射 + + // 页地图。每个bit都表示这个页是否被映射。 u8 *page_map; - // 分配器页地图 - // 每个bit表示这个页是否被内存分配器控制 - // (不代表每个页都包含完整的分配器) - u8 *map_with_allocator; - // 分配器释放页地图 - // 每个bit表示这个页是否曾经被内存分配器控制且现在被释放 - // 需要取消映射 - u8 *map_with_destructed_allocator; + // 分配器页地图。每个bit表示这个页是否被内存分配器控制。 + u8 *allocator_map; + // 释放的分配器页地图。每个bit表示这个页是否曾经被内存分配器控制且现在被释放。 + // 值为1的bit位对应的最小页可以直接**取消映射**、**重新构造一个分配器**、**加载可执行程序**等。 + u8 *destructed_allocator_map; // 空闲页线段搜索表 lst_iterator_t *available_pages_table; - // 分配器树 - // 为方便查找,以二叉树的形式存储 - // index=0为无效项 + // 分配器二叉树 allocator_iterator_t *allocators; -} mem_manager_t; +} memory_manager_t; -mem_manager_t *memm_new(usize mem_size); +/** + * @name memm_new + * + * ```c + * memory_manager_t *memm_new(usize mem_size); + * ``` + * + * 初始化内存管理结构。 + */ +memory_manager_t *memm_new(usize mem_size); -/* -在`start`处创建一个长度为`length`的内存分配器 -当`pid`为0时,表示这个分配器只给内核使用 +/** + * @name memm_get_manager + * + * ```c + * memory_manager_t *memm_get_manager(); + * ``` + * + * 在其它源代码文件中,获取内存管理结构的方式。 + */ +memory_manager_t *memm_get_manager(); + +/** + * @name memm_allocator_new + * + * ```c + * allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid); + * ``` + * + * 在`start`处创建一个长度为`length`的内存分配器,当`pid`为0时,表示这个分配器只给内核使用。 */ allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid); -/* -释放分配器对象 - -只能被内存回收模块调用 +/** + * @name memm_allocator_destruct + * + * ```c + * void memm_allocator_destruct(allocator_t *allocator); + * ``` + * + * 释放分配器对象。 + * + * 只能被**内存回收模块**调用。 */ void memm_allocator_destruct(allocator_t *allocator); -/* -申请内存 -pid=0时为内核分配 -所有内存在内核空间都有对物理内存空间的直接映射,也就是线性地址与物理地址相同,称为内核地址 - -allocator对象在进程与内核之间传递时一律使用内核空间的映射地址 - -## 要求在返回的地址前16字节处保留8字节空间作为它所在的allocator地址,并且不需要分配器的具体实现做这个事 +/** + * @name memm_allocate + * + * ```c + * void *memm_allocate(usize size, usize pid); + * ``` + * + * 申请内存。`pid`为0时为内核分配。 + * + * 所有内存在内核空间都有对物理内存空间的直接映射。 */ void *memm_allocate(usize size, usize pid); #define memm_addr_set_allocator(mem, allocator) \ - *(allocator_t **)((void *)(mem) - 16) = allocator; + *(allocator_t **)((void *)(mem)-16) = allocator; #define memm_addr_get_allocator(mem) \ - ((*(allocator_t **)((void *)(mem) - 16))) + ((*(allocator_t **)((void *)(mem)-16))) +/** + * @name memm_kernel_allocate + * + * ```c + * void *memm_kernel_allocate(usize size); + * ``` + * + * 为内核空间申请内存。 + */ void *memm_kernel_allocate(usize size); +/** + * @name memm_user_allocate + * + * ```c + * void *memm_user_allocate(usize size, usize pid); + * ``` + * + * 为用户空间申请内存。 + */ void *memm_user_allocate(usize size, usize pid); -/* -释放内存 +/** + * @name memm_free + * + * ```c + * void memm_free(void *mem); + * ``` + * + * 释放内存。 */ void memm_free(void *mem); -/* -寻找大小合适的一组页 +/** + * @name find_fitable_pages + * + * ```c + * usize find_fitable_pages(usize page_count); + * ``` + * 寻找大小合适的一组连续页 */ usize find_fitable_pages(usize page_count); diff --git a/include/kernel/memm/allocator/raw.h b/include/kernel/memm/allocator/raw.h index 9dc1784..a8d4112 100644 --- a/include/kernel/memm/allocator/raw.h +++ b/include/kernel/memm/allocator/raw.h @@ -24,6 +24,19 @@ typedef struct __raw_allocator_cell // // 统计从上次细胞合并以来free的调用次数,当调用次数很多或可用空间不足时 // 触发细胞合并。 +/** + * @name raw_allocator_t + * + * 原始分配器。包括至少一个cell,分配时像cell的分裂一样将空白的一段分成两段,释放时,只把length归零,并不将cell合并。 + * + * `length`为0的cell称为空cell。 + * + * 统计从上次细胞合并以来free的调用次数,当调用次数达到`RAW_ALLOCATOR_FREE_MAX`或无可用空间时触发细胞合并。 + * + * @internal free_count + * + * free方法的调用次数,达到`RAW_ALLOCATOR_FREE_MAX`时归零。 + */ typedef struct __raw_allocator_t { usize size; @@ -34,8 +47,22 @@ typedef struct __raw_allocator_t } raw_allocator_t; #define raw_allocator_end(allocator) ((void *)(allocator) + (allocator)->size) +/** + * @name raw_allocator_new + * + * ```c + * void raw_allocator_new(raw_allocator_t *allocator, usize size); + * ``` + * + * 初始化一个`raw_allocator`。 + */ void raw_allocator_new(raw_allocator_t *allocator, usize size); +/** + * @name raw_allocator_allocate, raw_allocator_free + * + * `raw_allocator`的一对allocate, free方法。 + */ void *raw_allocator_allocate(raw_allocator_t *allocator, usize size); void raw_allocator_free(raw_allocator_t *allocator, void *mem); diff --git a/include/kernel/syscall.h b/include/kernel/syscall.h index 1c9507a..fc2709b 100644 --- a/include/kernel/syscall.h +++ b/include/kernel/syscall.h @@ -5,6 +5,15 @@ #include #endif +/** + * @name syscall_init + * + * ```c + * void syscall_init(); + * ``` + * + * 初始化系统调用。 + */ void syscall_init(); #endif From 0613dadeaffdeb50abd94730be4271678a4abf3d Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Sun, 18 Feb 2024 03:54:48 +0800 Subject: [PATCH 09/37] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E4=BB=8Ec=E8=AF=AD=E8=A8=80=E4=BD=BF=E7=94=A8x86=5F64=E4=B8=AD?= =?UTF-8?q?sysret=E6=8C=87=E4=BB=A4=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kernel/arch/x86_64/entry.s | 3 +++ src/kernel/arch/x86_64/syscall_x86_64.s | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/kernel/arch/x86_64/entry.s b/src/kernel/arch/x86_64/entry.s index efbb1ad..54a341c 100644 --- a/src/kernel/arch/x86_64/entry.s +++ b/src/kernel/arch/x86_64/entry.s @@ -26,6 +26,9 @@ init64: lea rax, [systemcall_procedure] wrmsr + ; 加载中断相关寄存器 + ; 需要加载寄存器IA32_INTERRUPT_SSP_TABLE + jmp kmain section .multiboot2 align=8 diff --git a/src/kernel/arch/x86_64/syscall_x86_64.s b/src/kernel/arch/x86_64/syscall_x86_64.s index 8b9ae7a..d8220b7 100644 --- a/src/kernel/arch/x86_64/syscall_x86_64.s +++ b/src/kernel/arch/x86_64/syscall_x86_64.s @@ -50,6 +50,10 @@ set_kernel_stack_cache: pop rax ret +; void return_from_systemcall() +return_from_systemcall: + sysret + save_kernel_stack: endbr64 lea rbx, [kernel_stack_cache] From c52d9f4960b58889247314a62caee84c37e7944e Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Mon, 19 Feb 2024 01:03:27 +0800 Subject: [PATCH 10/37] =?UTF-8?q?=E5=B0=86=E9=A1=B5=E8=AE=A1=E6=95=B0?= =?UTF-8?q?=E7=A7=BB=E5=85=A5=E6=9E=B6=E6=9E=84=E6=94=AF=E6=8C=81=E4=B8=AD?= =?UTF-8?q?=EF=BC=88=E5=9B=A0=E4=B8=BA=E4=B8=8D=E5=90=8C=E7=9A=84=E6=9E=B6?= =?UTF-8?q?=E6=9E=84=E5=88=86=E9=A1=B5=E6=9C=BA=E5=88=B6=E4=B8=8D=E5=90=8C?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel/arch/x86_64/memm.h | 79 +++++++++++++++++----------- include/kernel/memm.h | 6 +-- src/kernel/arch/x86_64/memm_x86_64.c | 6 +-- 3 files changed, 52 insertions(+), 39 deletions(-) diff --git a/include/kernel/arch/x86_64/memm.h b/include/kernel/arch/x86_64/memm.h index 2702399..dc2ba65 100644 --- a/include/kernel/arch/x86_64/memm.h +++ b/include/kernel/arch/x86_64/memm.h @@ -7,9 +7,9 @@ /** * @name MEMM_PAGE_SIZE * @addindex 平台定制宏 - * + * * 最小的页大小。 - * + * * @if arch == x86_64 then * 4096 * @endif @@ -28,7 +28,7 @@ extern u64 PML4[512]; /** * @name MEMM_PAGE_TABLE_FLAGS_MASK * @addindex 平台依赖宏 x86_64 - * + * * 页表项中属性标志位使用的最低12位的掩码`0xfff`。 */ #define MEMM_PAGE_TABLE_FLAGS_MASK ((u64)0xfff) @@ -36,7 +36,7 @@ extern u64 PML4[512]; /** * @name MEMM_xx_ALIGN_MASK * @addindex 平台依赖宏 x86_64 - * + * * 页对齐掩码。 * `xx`为`x86_64`架构的页的三种大小,分别为`4K`、`2M`和`1G`。这些页一定是以它们自己的大小对齐,因此会出现低n位总为0的情况。 * `4K`对应`0xfff`;`2M`对应`0x1fffff`;`1G`对应`0x3fffffff`。 @@ -48,9 +48,9 @@ extern u64 PML4[512]; /** * @name MEMM_ENTRY_FLAG_xx * @addindex 平台依赖宏 x86_64 - * + * * 页表项属性标志位。定义如下: - * + * * ```c * #define MEMM_ENTRY_FLAG_PRESENT ((u64)1) * #define MEMM_ENTRY_FLAG_WRITE ((u64)1 << 1) @@ -65,7 +65,7 @@ extern u64 PML4[512]; * #define MEMM_PTE_ENTRY_FLAG_PAT ((u64)1 << 7) * #define MEMM_ENTRY_FLAG_XD ((u64)1 << 63) * ``` - * + * * 其中`MEMM_PTE_ENTRY_FLAG_PAT`的`pte`表示此属性标志位只存在与`pte`页表项中。 */ #define MEMM_ENTRY_FLAG_PRESENT ((u64)1) @@ -84,9 +84,9 @@ extern u64 PML4[512]; /** * @name memm_entry_flag_get(entry, flag) * @addindex 平台依赖宏 x86_64 - * + * * 获取页表项中某个属性标志位,得到布尔值。 - * + * * 其中`flag`是`MEMM_ENTRY_FLAG_xx`。 */ #define memm_entry_flag_get(entry, flag) \ @@ -95,13 +95,13 @@ extern u64 PML4[512]; /** * @name MEMM_ENTRY_ADDRESS_MASK, MEMM_BP_ENTRY_ADDRESS_MASK * @addindex 平台依赖宏 x86_64 - * + * * 页表项地址域掩码。将页表项与掩码作与运算可得到页表项指向的**下一级页表的起始地址**或**页框的起始地址**。 - * + * * 含`BP`的为大型页页表项的地址域掩码。 - * + * * 定义如下: - * + * * ```c * #define MEMM_ENTRY_ADDRESS_MASK ((u64)0x000ffffffffff000) * #define MEMM_BP_ENTRY_ADDRESS_MASK ((u64)0x000fffffffffe000) @@ -113,7 +113,7 @@ extern u64 PML4[512]; /** * @name memm_entry_get_address(entry) * @addindex 平台依赖宏 x86_64 - * + * * 获取页表项指向的地址。 */ #define memm_entry_get_address(entry) \ @@ -138,7 +138,7 @@ extern u64 PML4[512]; /** * @name MEMM_LA_xxxxI * @addindex 平台依赖宏 x86_64 - * + * * 在4级分页中,线性地址的四个页表项索引宏。其中`xxxx`分别为`PML4E`、`PDPTE`、`PDE`和`PE`。 */ #define MEMM_LA_PML4EI @@ -149,9 +149,9 @@ extern u64 PML4[512]; /** * @name memm_la_get_entry_index(addr, entry) * @addindex 平台依赖宏 x86_64 - * + * * 获取线性地址`addr`中的`entry`页表项索引。 - * + * * 其中`entry`应为宏`MEMM_LA_xxxxI`。 */ #define memm_la_get_entry_index(addr, entry) \ @@ -160,7 +160,7 @@ extern u64 PML4[512]; /** * @name MEMM_LA_xxx_PAGE_OFFSET * @addindex 平台依赖宏 x86_64 - * + * * 线性地址的页内偏移宏。其中`xxx`为三种页容量`4KB`、`2MB`、`1GB`。 */ #define MEMM_LA_1GB_PAGE_OFFSET @@ -170,9 +170,9 @@ extern u64 PML4[512]; /** * @name memm_la_get_offset(addr, page_type) * @addindex 平台依赖宏 x86_64 - * + * * 获取线性地址的页内偏移部分。 - * + * * 其中`page_type`应为宏`MEMM_LA_xxx_PAGE_OFFSET`。 */ #define memm_la_get_offset(addr, page_type) \ @@ -180,20 +180,20 @@ extern u64 PML4[512]; /** * @name memm_map_pageframes_to - * + * * ```c * bool memm_map_pageframes_to( * u64 target, u64 physical, * usize size, * bool user, bool write); * ``` - * + * * 仅支持**canonical**型地址 - * + * * `target`与`physical`保证至少都是以MEMM_PAGE_SIZE对齐的。 - * + * * 没有MEMM_PAGE_SIZE对齐的,和非canonical型地址都会返回false - * + * * 当剩余长度超过1GB的一半且地址1GB对齐,则会映射一个1GB页; * 当剩余长度超过2MB的一半且地址2MB对齐,则会映射一个2MB页; * 否则映射4KB页。 @@ -206,7 +206,7 @@ bool memm_map_pageframes_to( /** * @name reload_pml4 * @addindex 平台依赖宏 x86_64 - * + * * ```c * void reload_pml4(); * ``` @@ -216,9 +216,9 @@ extern void reload_pml4(); /** * @name is_user_address(addr) * @addindex 平台定制宏 - * + * * 判断`addr`是否是一个用户空间地址,得到一个布尔值。 - * + * * @if arch == x86_64 * `canonical`型地址的高地址为用户空间,低地址为内核空间。 * @endif @@ -229,7 +229,7 @@ extern void reload_pml4(); /** * @name is_cannonical(addr) * @addindex 平台依赖宏 x86_64 - * + * * 判断`addr`是否是一个cannonical型地址。 */ #define is_cannonical(addr) \ @@ -238,9 +238,9 @@ extern void reload_pml4(); /** * @name memm_get_page_align(addr) * @addindex 平台依赖宏 x86_64 - * + * * 获取地址`addr`的页对齐大小,得到一个`memm_page_size`类型值。 - * + * * 当地址`addr`是*4KB对齐*或*没有4KB对齐时*,都得到`MEMM_PAGE_SIZE_4K`。 */ #define memm_get_page_align(addr) \ @@ -250,4 +250,21 @@ extern void reload_pml4(); ? MEMM_PAGE_SIZE_2M \ : MEMM_PAGE_SIZE_4K)) +/** + * @name memm_page_counter + * @addindex 平台定制结构 + * + * 页计数器 + * + * @if arch == x86_64 + * 使用三个成员分别记录`4KB`、`2MB`、`1GB`页的大小。 + * @endif + */ +typedef struct __memm_page_counter +{ + usize mapped_4k_page; + usize mapped_2m_page; + usize mapped_1g_page; +} memm_page_counter; + #endif diff --git a/include/kernel/memm.h b/include/kernel/memm.h index 0074ca8..f522507 100644 --- a/include/kernel/memm.h +++ b/include/kernel/memm.h @@ -186,11 +186,7 @@ typedef struct __mem_manager_t // 已经映射的页数量。若不是最小的页会被视作多个最小页计数。 usize mapped_page_amount; -#ifdef __x86_64__ - usize mapped_4k_page; - usize mapped_2m_page; - usize mapped_1g_page; -#endif + memm_page_counter platformed_page_counter; // 页地图。每个bit都表示这个页是否被映射。 u8 *page_map; diff --git a/src/kernel/arch/x86_64/memm_x86_64.c b/src/kernel/arch/x86_64/memm_x86_64.c index 080de11..e924ab6 100644 --- a/src/kernel/arch/x86_64/memm_x86_64.c +++ b/src/kernel/arch/x86_64/memm_x86_64.c @@ -126,11 +126,11 @@ bool memm_map_pageframes_to( switch (align) { case MEMM_PAGE_SIZE_4K: - mm->mapped_4k_page++; + mm->platformed_page_counter.mapped_4k_page++; case MEMM_PAGE_SIZE_2M: - mm->mapped_2m_page++; + mm->platformed_page_counter.mapped_2m_page++; case MEMM_PAGE_SIZE_1G: - mm->mapped_1g_page++; + mm->platformed_page_counter.mapped_1g_page++; } for (usize i = physical / MEMM_PAGE_SIZE; i < physical / MEMM_PAGE_SIZE + align; i++) { From aedcb8749ee10b791112b469936729126af8a620 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Mon, 19 Feb 2024 01:43:12 +0800 Subject: [PATCH 11/37] =?UTF-8?q?Message=E7=B1=BB=E5=9E=8B=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0to=5Fstring=E6=96=B9=E6=B3=95=E7=94=A8=E4=BA=8E?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96=E5=AD=97=E7=AC=A6=E4=B8=B2=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E5=A2=9E=E5=8A=A0=E8=B4=A1=E7=8C=AE=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E7=9A=84=E4=B8=80=E4=BA=9B=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/contribution.md | 7 +++++++ src/kernel/klog.rs | 3 +-- src/kernel/tty/tty.rs | 14 ++++++++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/docs/contribution.md b/docs/contribution.md index 622a26b..e66325d 100644 --- a/docs/contribution.md +++ b/docs/contribution.md @@ -11,3 +11,10 @@ * 等待审核代码 若你的代码通过审核,将会把你的PR合并到主分支中。 + +## 需要注意的还未解决的问题 + +* rust中所有有关字符串格式化的宏中,出现超过一个不止是`{}`的格式化占位符时内核必然崩溃。 +* rust中所有有关字符串格式化的宏中,出现需要调用自定义的`Debug trait`的类型时内核必然崩溃,推荐定义`ToString trait`并调用`.to_string()`后传入宏参数。 +* 鉴于以上两条原因,不建议在复杂的字符串格式化任务中使用`format!()`宏。推荐通过使用`::kernel::tty::tty::MessageBuilder`构造`kernel::tty::tty::Message`对象,或使用 + `message`宏,并调用此对象的`.to_string()`方法实现格式化字符串。 diff --git a/src/kernel/klog.rs b/src/kernel/klog.rs index 756d84d..628c0ee 100644 --- a/src/kernel/klog.rs +++ b/src/kernel/klog.rs @@ -1,4 +1,3 @@ -use alloc::string::ToString; use alloc::vec; use alloc::vec::Vec; @@ -181,7 +180,7 @@ impl<'a> Iterator for LogIterator<'a> { let res = if let Some((time, msg)) = self.logs.first() { Some( MessageBuilder::new() - .message(&time.to_string()) + .message(time) .append(MessageBuilder::from_message(msg.clone())) .build(), ) diff --git a/src/kernel/tty/tty.rs b/src/kernel/tty/tty.rs index 50b1470..aa3027a 100644 --- a/src/kernel/tty/tty.rs +++ b/src/kernel/tty/tty.rs @@ -181,6 +181,16 @@ pub struct MessageSection { #[derive(Clone)] pub struct Message(Vec); +impl ToString for Message { + fn to_string(&self) -> String { + let mut res = String::new(); + for MessageSection { msg, .. } in self.0.iter() { + res += msg; + } + res + } +} + /// ## MessageBuilder /// /// 使用链式调用模式构造一个消息. @@ -226,7 +236,7 @@ impl MessageBuilder { Self { msg } } - pub fn message(mut self, msg: &str) -> Self { + pub fn message(mut self, msg: &T) -> Self { self.msg.0.push(MessageSection { msg: msg.to_string(), fgcolor: Color(0xee, 0xee, 0xee), @@ -235,7 +245,7 @@ impl MessageBuilder { self } - pub fn message_mut(&mut self, msg: &str) { + pub fn message_mut(&mut self, msg: &T) { self.msg.0.push(MessageSection { msg: msg.to_string(), fgcolor: Color(0xee, 0xee, 0xee), From 2aaa5926366ff85366c131911433ff55733f210e Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Mon, 19 Feb 2024 01:47:16 +0800 Subject: [PATCH 12/37] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=88=86=E9=85=8D?= =?UTF-8?q?=E5=99=A8=E6=88=90=E5=91=98=EF=BC=9A=20=E7=A7=BB=E9=99=A4initia?= =?UTF-8?q?lized=EF=BC=8C=E5=A2=9E=E5=8A=A0userspace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel/memm.h | 30 +++++++++++++++++++++--------- src/kernel/memm/memm.c | 9 ++++----- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/include/kernel/memm.h b/include/kernel/memm.h index f522507..e83bbaa 100644 --- a/include/kernel/memm.h +++ b/include/kernel/memm.h @@ -35,9 +35,9 @@ * * 分配器的一对`分配`、`释放`函数指针。内核中可以根据情况使用多种不同的分配器来分配内存,`allocator`中提供一对此类型的变量,用于 * 动态绑定不同的分配器。 - * + * * 分配器在`kernel/memm/allocator/`中定义。 - * + * * 分配器**必须**实现的行为: * * **`memm_allocate_t`**: @@ -78,7 +78,11 @@ typedef void (*memm_free_t)(void *allocator, void *mem); * 在**内核镜像结尾**至`MEMM_ALLOC_ONLY_MEMORY`空间中,包含一个分配器`内核大分配器`。 * * 分配器指针**必须**使用内核地址。 - * + * + * @internal magic + * + * 分配器有效性由此检验,不为`MEMM_ALLOCATOR_MAGIC_NUM`说明获得了一个错误的分配器地址。 + * * @internal full * * 调用分配器的`allocate`方法后,在返回`nullptr`时会设为`true`。 @@ -88,6 +92,10 @@ typedef void (*memm_free_t)(void *allocator, void *mem); * * 进程标志服,表示此分配器所属的进程,为0代表属于内核。 * + * @internal userspace + * + * 若分配器不属于内核,此成员储存此分配器的用户空间地址。 + * * @internal type * * 分配器类型。在目录`include/kernel/memm/allocator`中对每个分配器分别定义一个唯一值。 @@ -107,17 +115,21 @@ typedef void (*memm_free_t)(void *allocator, void *mem); */ typedef struct __allocator_t { -#define MEMM_ALLOCATOR_MAGIC_NUM 0x271fe441 +#ifndef MEMM_ALLOCATOR_MAGIC +#define MEMM_ALLOCATOR_MAGIC 0x271fe441 +#endif + // 分配器有效性由此检验,不为`MEMM_ALLOCATOR_MAGIC_NUM`说明获得了一个错误的分配器地址。 + // 此值在编译时通过各种方式确定,若 u32 magic; - bool initialized; - // 调用分配器的`allocate`方法后,在返回`nullptr`时会设为`true`。 // 调用分配器的`free`方法时设为`false`。 bool full; // 进程标志服,表示此分配器所属的进程,为0代表属于内核。 usize pid; + // 若分配器不属于内核,此成员储存此分配器的用户空间地址。 + void *userspace; // 分配器类型。在目录`include/kernel/memm/allocator`中对每个分配器分别定义一个唯一值。 usize type; usize size; @@ -290,18 +302,18 @@ void *memm_user_allocate(usize size, usize pid); /** * @name memm_free - * + * * ```c * void memm_free(void *mem); * ``` - * + * * 释放内存。 */ void memm_free(void *mem); /** * @name find_fitable_pages - * + * * ```c * usize find_fitable_pages(usize page_count); * ``` diff --git a/src/kernel/memm/memm.c b/src/kernel/memm/memm.c index f2cbf71..513a7f5 100644 --- a/src/kernel/memm/memm.c +++ b/src/kernel/memm/memm.c @@ -77,8 +77,7 @@ memory_manager_t *memm_get_manager() allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid) { allocator_t *allocator = start; - allocator->magic = MEMM_ALLOCATOR_MAGIC_NUM; - allocator->initialized = true; + allocator->magic = MEMM_ALLOCATOR_MAGIC; allocator->full = false; allocator->pid = 0; allocator->size = length; @@ -91,14 +90,14 @@ allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid allocator->free = (memm_free_t)raw_allocator_free; break; default: - allocator->initialized = false; + allocator->magic = 0; break; } } void memm_allocator_destruct(allocator_t *allocator) { - allocator->initialized = false; + allocator->magic = 0; // TODO 从分配器树中删除这个分配器 KERNEL_TODO(); } @@ -226,7 +225,7 @@ void *memm_user_allocate(usize size, usize pid) void memm_free(void *mem) { allocator_t *allocator = memm_addr_get_allocator(mem); - if (allocator->magic != MEMM_ALLOCATOR_MAGIC_NUM) + if (allocator->magic != MEMM_ALLOCATOR_MAGIC) return; if (is_user_address((u64)mem)) { // TODO 对于用户空间的地址需要先转换到内核地址后释放 From 501643f86a6dcd31147e2c8594db503f6e6fd9ce Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Mon, 19 Feb 2024 02:29:11 +0800 Subject: [PATCH 13/37] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=88=86=E9=85=8D?= =?UTF-8?q?=E5=99=A8=E6=88=90=E5=91=98=EF=BC=9A=20=E7=A7=BB=E9=99=A4initia?= =?UTF-8?q?lized=EF=BC=8C=E5=A2=9E=E5=8A=A0userspace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kernel/memm/memm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/kernel/memm/memm.c b/src/kernel/memm/memm.c index 513a7f5..34898c5 100644 --- a/src/kernel/memm/memm.c +++ b/src/kernel/memm/memm.c @@ -228,7 +228,8 @@ void memm_free(void *mem) if (allocator->magic != MEMM_ALLOCATOR_MAGIC) return; if (is_user_address((u64)mem)) - { // TODO 对于用户空间的地址需要先转换到内核地址后释放 + { + mem = mem - allocator->userspace + (void *)allocator; } allocator->free(allocator->allocator_instance, mem); if (allocator->full) From 25116eaee46a977afc0b3d4308916177e071a0fd Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Mon, 19 Feb 2024 05:15:22 +0800 Subject: [PATCH 14/37] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=97=B6=E7=A1=AE=E5=AE=9A=E7=9A=84allocator=5Fmagic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Makefile | 4 +++- src/kernel/Makefile | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index 7ccfc6c..00bec68 100644 --- a/src/Makefile +++ b/src/Makefile @@ -12,9 +12,11 @@ ifdef release release = 1 endif +ALLOCATOR_MAGIC = $(shell doas hwclock | sha512sum | head -c 128 | md5sum | head -c 8) + SUBOBJS = kernel/kernel.o libk/libk.o rust.o -DEFINES = ARCH="${ARCH}" ASM="${ASM}" ASMFLAGS="${ASMFLAGS}" SOURCE="${SOURCE}" PWD="${PWD}" +DEFINES = ARCH="${ARCH}" ASM="${ASM}" ASMFLAGS="${ASMFLAGS}" SOURCE="${SOURCE}" PWD="${PWD}" ALLOCATOR_MAGIC="${ALLOCATOR_MAGIC}" ifdef release DEFINES := ${DEFINES} release=1 endif diff --git a/src/kernel/Makefile b/src/kernel/Makefile index f47b005..e4ab8de 100644 --- a/src/kernel/Makefile +++ b/src/kernel/Makefile @@ -6,7 +6,8 @@ CC = gcc CCFLAGS = -m64 -mcmodel=large -I ../../include \ -fno-stack-protector -fno-exceptions \ - -fno-builtin -nostdinc -nostdlib + -fno-builtin -nostdinc -nostdlib \ + -DMEMM_ALLOCATOR_MAGIC=\"${ALLOCATOR_MAGIC}\" ifdef release CCFLAGS := ${CCFLAGS} -O2 endif From f64ff62b754c8bdc2ee5709710d380c78d4040c8 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Sun, 25 Feb 2024 20:46:56 +0800 Subject: [PATCH 15/37] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AF=B9=E7=89=B9?= =?UTF-8?q?=E5=AE=9A=E6=9E=B6=E6=9E=84=E5=86=85=E5=AD=98=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=83=85=E5=86=B5=E7=9A=84=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel/arch/x86_64/memm.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/kernel/arch/x86_64/memm.h b/include/kernel/arch/x86_64/memm.h index dc2ba65..a307981 100644 --- a/include/kernel/arch/x86_64/memm.h +++ b/include/kernel/arch/x86_64/memm.h @@ -4,6 +4,18 @@ #include #include +/** + * @details x86_64 + * + * 物理地址空间: + * + * * 0 \~ 2MB:不使用,不映射 + * * 2MB \~ 4MB:中断栈。 + * * 4MB \~ 16MB:内核栈。 + * * 16MB \~ ?:内核镜像。 + * * ? \~ 128MB:内核大分配器。 + */ + /** * @name MEMM_PAGE_SIZE * @addindex 平台定制宏 From 622f017b6a636e7a29f672238de4336190795b68 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Mon, 26 Feb 2024 01:58:49 +0800 Subject: [PATCH 16/37] =?UTF-8?q?=E6=95=B4=E7=90=86=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E4=B9=B1=E4=B8=83=E5=85=AB=E7=B3=9F=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel/memm.h | 2 +- src/kernel/Makefile | 2 +- src/kernel/klog.rs | 2 +- src/kernel/tty/tty.rs | 13 +++++++++++++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/include/kernel/memm.h b/include/kernel/memm.h index e83bbaa..2ba8920 100644 --- a/include/kernel/memm.h +++ b/include/kernel/memm.h @@ -116,7 +116,7 @@ typedef void (*memm_free_t)(void *allocator, void *mem); typedef struct __allocator_t { #ifndef MEMM_ALLOCATOR_MAGIC -#define MEMM_ALLOCATOR_MAGIC 0x271fe441 +#define MEMM_ALLOCATOR_MAGIC ((u32)0x271fe441) #endif // 分配器有效性由此检验,不为`MEMM_ALLOCATOR_MAGIC_NUM`说明获得了一个错误的分配器地址。 // 此值在编译时通过各种方式确定,若 diff --git a/src/kernel/Makefile b/src/kernel/Makefile index e4ab8de..83c5271 100644 --- a/src/kernel/Makefile +++ b/src/kernel/Makefile @@ -7,7 +7,7 @@ CC = gcc CCFLAGS = -m64 -mcmodel=large -I ../../include \ -fno-stack-protector -fno-exceptions \ -fno-builtin -nostdinc -nostdlib \ - -DMEMM_ALLOCATOR_MAGIC=\"${ALLOCATOR_MAGIC}\" + -DMEMM_ALLOCATOR_MAGIC="(u32)(0x${ALLOCATOR_MAGIC})" ifdef release CCFLAGS := ${CCFLAGS} -O2 endif diff --git a/src/kernel/klog.rs b/src/kernel/klog.rs index 628c0ee..8c55f00 100644 --- a/src/kernel/klog.rs +++ b/src/kernel/klog.rs @@ -139,7 +139,7 @@ impl KernelLogger { return false; } } - return true; + true }; while !all_end(&indeces, &logs) { let mut min_ind = None; diff --git a/src/kernel/tty/tty.rs b/src/kernel/tty/tty.rs index aa3027a..f817e51 100644 --- a/src/kernel/tty/tty.rs +++ b/src/kernel/tty/tty.rs @@ -206,6 +206,19 @@ impl ToString for Message { /// .build(); /// ``` /// +/// 定义了`message!`宏,简化构造消息的代码: +/// +/// ```rust +/// use crate::kernel::tty::tty::BuilderFunctions::*; +/// +/// message!( +/// Msg("Hello, "), +/// Msg("Metaverse"), +/// FgColor(Color::GREEN), +/// Msg("!\n"), +/// ); +/// ``` +/// /// 对于特殊情况可以使用非链式调用: /// ```rust /// let mut msg = MessageBuilder::new(); From 925ff4777daa5434ef6485d6744c6e3894d11d68 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Mon, 26 Feb 2024 22:02:58 +0800 Subject: [PATCH 17/37] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=AD=E6=96=AD?= =?UTF-8?q?=E5=90=91=E9=87=8F=E8=A1=A8=E5=8F=8ATSS=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel/arch/x86_64/interrupt.h | 10 +++++----- include/kernel/arch/x86_64/kernel.h | 2 ++ src/kernel/arch/x86_64/entry.s | 3 --- src/kernel/arch/x86_64/entry32.s | 26 +++++++++++++++++++++----- src/metaverse.lds | 6 +++++- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/include/kernel/arch/x86_64/interrupt.h b/include/kernel/arch/x86_64/interrupt.h index 04c9dfd..8e2dc9a 100644 --- a/include/kernel/arch/x86_64/interrupt.h +++ b/include/kernel/arch/x86_64/interrupt.h @@ -7,7 +7,7 @@ /** * @name gate_descriptor_t * @addindex 平台依赖结构 x86_64 - * + * * 门描述符的结构体形式。 */ typedef struct __gate_descriptor_t @@ -23,12 +23,12 @@ typedef struct __gate_descriptor_t /** * @name INTERRUPT_DESCRIPTOR_FLAG_IST * @addindex 平台依赖结构 x86_64 - * + * * `gate_descriptor_t`的`flags`的标志位。 - * + * * `ssp`代表一个tss描述符在任务段中的的索引。 */ -#define INTERRUPT_DESCRIPTOR_FLAG_IST(ssp) (ssp) +#define INTERRUPT_DESCRIPTOR_FLAG_IST 1 // 在第15位上有一个表示代码段是否存在的标志位,代码段总是存在,故直接设置为1 #define INTERRUPT_DESCRIPTOR_FLAG_TYPE_INTERRUPT (0x8e << 8) @@ -36,7 +36,7 @@ typedef struct __gate_descriptor_t /** * @name idt - * + * * 中断描述符表。 */ extern gate_descriptor_t idt[256]; diff --git a/include/kernel/arch/x86_64/kernel.h b/include/kernel/arch/x86_64/kernel.h index 5ac5529..af07ab4 100644 --- a/include/kernel/arch/x86_64/kernel.h +++ b/include/kernel/arch/x86_64/kernel.h @@ -12,4 +12,6 @@ */ extern void prepare_stack(); +extern u32 TSS[26]; + #endif diff --git a/src/kernel/arch/x86_64/entry.s b/src/kernel/arch/x86_64/entry.s index 54a341c..efbb1ad 100644 --- a/src/kernel/arch/x86_64/entry.s +++ b/src/kernel/arch/x86_64/entry.s @@ -26,9 +26,6 @@ init64: lea rax, [systemcall_procedure] wrmsr - ; 加载中断相关寄存器 - ; 需要加载寄存器IA32_INTERRUPT_SSP_TABLE - jmp kmain section .multiboot2 align=8 diff --git a/src/kernel/arch/x86_64/entry32.s b/src/kernel/arch/x86_64/entry32.s index f68326e..e05cffb 100644 --- a/src/kernel/arch/x86_64/entry32.s +++ b/src/kernel/arch/x86_64/entry32.s @@ -47,7 +47,7 @@ init32: ; 设置gdt_ptr mov eax, 0x10402a ; gdt_ptr + 2 mov dword [eax], 0x104000 ; gdt - ; 加载GDTR和段寄存器 + ; 加载GDTR、段寄存器和TR寄存器 db 0x66 lgdt [0x104028] ; gdt_ptr mov ax, 0x10 @@ -56,6 +56,8 @@ init32: mov es, ax mov fs, ax mov gs, ax + mov ax, 0x30 + ltr ax ; 打开PAE mov eax, cr4 @@ -99,10 +101,13 @@ PD0: ; 分段 gdt: dq 0 - dq 0x0020980000000000 ; 内核态代码段 - dq 0x0000920000000000 ; 内核态数据段 - dq 0x0020f80000000000 ; 用户态代码段 - dq 0x0000f20000000000 ; 用户态数据段 + dq 0x0020980000000000 ; 内核态代码段 + dq 0x0000920000000000 ; 内核态数据段 + dq 0x0020f80000000000 ; 用户态代码段 + dq 0x0000f20000000000 ; 用户态数据段 + dq 0 + dq 0x0000891060000000 ; TSS段(低64位) + dq 0 ; TSS段(高64位) gdt_end: gdt_ptr: ; 0x104028 @@ -120,3 +125,14 @@ idt_ptr: ; 0x104038 global idt idt: resq 512 ; 16 bytes per descriptor (512 q-bytes) + + section .cpumeta.tss alogn=4096 + global TSS +TSS: + dd 0 + dq 0x1000000 ; (rsp0)内核栈 + dq 0 ; (rsp1) + dq 0 ; (rsp2) + dq 0 + dq 0x400000 ; (ist1)中断栈 + resb 104 - ($ - TSS) diff --git a/src/metaverse.lds b/src/metaverse.lds index 87da7f2..f4b2bdb 100644 --- a/src/metaverse.lds +++ b/src/metaverse.lds @@ -13,10 +13,14 @@ SECTIONS { { *(.multiboot2) } - .cpumeta : + .cpumeta ALIGN(4096) : { *(.cpumeta) } + .cpumeta.tss ALIGN(4096) : + { + *(.cpumeta.tss) + } . = 16M; .text : { From 2f0f12f893c1fedab65fde192961347f7ce6ef75 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Tue, 27 Feb 2024 22:18:14 +0800 Subject: [PATCH 18/37] =?UTF-8?q?=E8=A7=A3=E5=86=B3idt=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kernel/arch/x86_64/entry.s | 3 ++- src/kernel/arch/x86_64/entry32.s | 44 +++++++++++++------------------- src/metaverse.lds | 12 +++++++++ 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/kernel/arch/x86_64/entry.s b/src/kernel/arch/x86_64/entry.s index efbb1ad..2647c42 100644 --- a/src/kernel/arch/x86_64/entry.s +++ b/src/kernel/arch/x86_64/entry.s @@ -6,12 +6,13 @@ init64: endbr64 cli - ; 加载段寄存器 mov rax, 0x1000000 mov rbp, rax mov rsp, rax mov rdi, rbx + lidt [0x104010] + ; 加载系统调用相关寄存器 ; IA32_STAR = 0x0018_0008_0000_0000 mov rcx, 0xc0000081 diff --git a/src/kernel/arch/x86_64/entry32.s b/src/kernel/arch/x86_64/entry32.s index e05cffb..dc63960 100644 --- a/src/kernel/arch/x86_64/entry32.s +++ b/src/kernel/arch/x86_64/entry32.s @@ -37,19 +37,9 @@ 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 ; 加载GDTR、段寄存器和TR寄存器 db 0x66 - lgdt [0x104028] ; gdt_ptr + lgdt [0x104000] ; gdt_ptr mov ax, 0x10 mov ds, ax mov ss, ax @@ -98,7 +88,20 @@ PDPT0: PD0: resq 512 - ; 分段 + section .cpumeta.tblptrs + +gdt_ptr: ; 0x104000 + dw gdt_end - gdt - 1 + dq gdt + + dd 0 + dw 0 + +idt_ptr: ; 0x104010 + dw 0x7ff + dq idt + + section .cpumeta.gdt align=4096 gdt: dq 0 dq 0x0020980000000000 ; 内核态代码段 @@ -106,27 +109,16 @@ gdt: dq 0x0020f80000000000 ; 用户态代码段 dq 0x0000f20000000000 ; 用户态数据段 dq 0 - dq 0x0000891060000000 ; TSS段(低64位) + dq 0x0000891070000000 ; TSS段(低64位) dq 0 ; TSS段(高64位) gdt_end: -gdt_ptr: ; 0x104028 - dw gdt_end - gdt - 1 - dq gdt - - resb 6 - -idt_ptr: ; 0x104038 - dw 0x7ff - dq idt - - resb 14 - + section .cpumeta.idt align=4096 global idt idt: resq 512 ; 16 bytes per descriptor (512 q-bytes) - section .cpumeta.tss alogn=4096 + section .cpumeta.tss align=4096 global TSS TSS: dd 0 diff --git a/src/metaverse.lds b/src/metaverse.lds index f4b2bdb..1c8009e 100644 --- a/src/metaverse.lds +++ b/src/metaverse.lds @@ -17,6 +17,18 @@ SECTIONS { { *(.cpumeta) } + .cpumeta.tblptrs ALIGN(4096) : + { + *(cpumeta.tblptrs) + } + .cpumeta.gdt ALIGN(4096) : + { + *(.cpumeta.gdt) + } + .cpumeta.idt ALIGN(4096) : + { + *(.cpumeta.idt) + } .cpumeta.tss ALIGN(4096) : { *(.cpumeta.tss) From 6f14cd6322896b3f0cbe8f93e4756cc908a69d4b Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Thu, 29 Feb 2024 11:36:56 +0800 Subject: [PATCH 19/37] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E4=B8=8D=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E7=9A=84=E6=9C=89=E5=85=B3=E5=9C=B0=E5=9D=80=E6=9B=BF?= =?UTF-8?q?=E6=8D=A2=E7=9A=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kernel/arch/x86_64/entry32.s | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/kernel/arch/x86_64/entry32.s b/src/kernel/arch/x86_64/entry32.s index dc63960..1dba72f 100644 --- a/src/kernel/arch/x86_64/entry32.s +++ b/src/kernel/arch/x86_64/entry32.s @@ -1,9 +1,6 @@ section .entry extern init64 ; 寄存器ebx是multiboot2 information,不可以使用 - ; - ; 由于这个代码是32位环境的代码,而链接器链接时会把它当作64位代码链接 - ; 所以这里所有的使用了常数的位置都要通过指令写入 init32: cli @@ -76,7 +73,6 @@ init32: section .cpumeta align=4096 global PML4 ; 分页 - ; 链接器会把这些数据替换掉所以要在代码中重新设置 PML4: dq 0x003 + PDPT0 resq 511 From 320ceaa56dff2ce20ae9164b3d8221158d5556d7 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Fri, 1 Mar 2024 01:47:06 +0800 Subject: [PATCH 20/37] =?UTF-8?q?=E5=A2=9E=E5=8A=A0raw=20allocator?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E5=BB=BA=E8=AE=AE=E3=80=82=20=E6=94=B9?= =?UTF-8?q?=E5=8F=98=E4=BD=8E=E5=9C=B0=E5=9D=80=E6=98=A0=E5=B0=84=E7=AD=96?= =?UTF-8?q?=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 5 ++++- include/kernel/arch/x86_64/memm.h | 3 ++- include/kernel/memm/allocator/raw.h | 10 ++-------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index a77927d..3316f1c 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ SOURCE := $(shell pwd)/src/scripts -.PHONY: all clear run debug config +.PHONY: all clear run debug config disass all: config @make -C src all --no-print-directory @@ -25,3 +25,6 @@ config: touch metaverse_kernel; \ "${SOURCE}/depcheck"; \ fi + +disass: + objdump -D src/metaverse.elf > kerndisass.txt diff --git a/include/kernel/arch/x86_64/memm.h b/include/kernel/arch/x86_64/memm.h index a307981..1fc1d31 100644 --- a/include/kernel/arch/x86_64/memm.h +++ b/include/kernel/arch/x86_64/memm.h @@ -9,7 +9,8 @@ * * 物理地址空间: * - * * 0 \~ 2MB:不使用,不映射 + * * 0 \~ 1MB:保留。 + * * 1MB \~ 2MB:内核头。 * * 2MB \~ 4MB:中断栈。 * * 4MB \~ 16MB:内核栈。 * * 16MB \~ ?:内核镜像。 diff --git a/include/kernel/memm/allocator/raw.h b/include/kernel/memm/allocator/raw.h index a8d4112..d9d1258 100644 --- a/include/kernel/memm/allocator/raw.h +++ b/include/kernel/memm/allocator/raw.h @@ -16,14 +16,6 @@ typedef struct __raw_allocator_cell } raw_allocator_cell; #define raw_allocator_next_cell(cell) (raw_allocator_cell *)((void *)((cell)->content) + (cell)->capacity) -// 原始分配器 -// -// 包括至少一个cell,分配时像cell的分裂一样将空白的一段分成两段, -// 释放时,只把length归零,并不将cell合并。 -// length=0的cell称为空cell -// -// 统计从上次细胞合并以来free的调用次数,当调用次数很多或可用空间不足时 -// 触发细胞合并。 /** * @name raw_allocator_t * @@ -33,6 +25,8 @@ typedef struct __raw_allocator_cell * * 统计从上次细胞合并以来free的调用次数,当调用次数达到`RAW_ALLOCATOR_FREE_MAX`或无可用空间时触发细胞合并。 * + * 使用建议:只在少量allocate和free的情况下使用。使用大量allocate时效率低下并难以得到内存安全保证。 + * * @internal free_count * * free方法的调用次数,达到`RAW_ALLOCATOR_FREE_MAX`时归零。 From 2144ad5123202da5e3809b43f031115d663993d9 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Tue, 5 Mar 2024 01:18:26 +0800 Subject: [PATCH 21/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E7=9A=84=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Makefile | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/Makefile b/src/Makefile index 00bec68..7d5a4bb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -37,7 +37,7 @@ ifeq (${ARCH},x86_64) endif ifdef release - RSCFLAGS := -O + RSCFLAGS := ${RSCFLAGS} -O endif ifeq (${ARCH},x86_64) @@ -69,16 +69,24 @@ postproc: @echo -e "\e[0m" kernel: - @echo -e "\e[33m__\e[0m \e[1;35m[Building kernel]\e[0m \e[33m____\e[0m" + @if [ ! ${release} ]; then \ + echo -e "\e[33m__\e[0m \e[1;35m[Building kernel]\e[0m \e[33m____\e[0m"; \ + fi @make -C kernel all --no-print-directory ${DEFINES} - @echo -e "\e[33m-------------------------\e[0m" + @if [ ! ${release} ]; then \ + echo -e "\e[33m-------------------------\e[0m"; \ + fi libk: - @echo -e "\e[33m__\e[0m \e[1;35m[Building libk]\e[0m \e[33m______\e[0m" + @if [ ! ${release} ]; then \ + echo -e "\e[33m__\e[0m \e[1;35m[Building libk]\e[0m \e[33m______\e[0m"; \ + fi @make -C libk all --no-print-directory ${DEFINES} - @echo -e "\e[33m-------------------------\e[0m" + @if [ ! ${release} ]; then \ + echo -e "\e[33m-------------------------\e[0m"; \ + fi -rust: +rust: postproc @echo -e "\e[1m\e[33mrustc\e[0m \e[34m-->\e[0m \e[1m\e[32m$@.o\e[0m" @rustc ${RSCFLAGS} lib.rs -o rust.o From ba6e23ee991c902052a18fb6a7de443ea40378fd Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Tue, 5 Mar 2024 23:34:02 +0800 Subject: [PATCH 22/37] =?UTF-8?q?=E5=A2=9E=E5=8A=A0tty=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E9=A2=9C=E8=89=B2=E7=9A=84=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel/tty.h | 18 ++++++++++++++---- src/kernel/tty/tty.rs | 7 ++++--- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/include/kernel/tty.h b/include/kernel/tty.h index 2a1e6c3..6edf00d 100644 --- a/include/kernel/tty.h +++ b/include/kernel/tty.h @@ -99,8 +99,8 @@ tty **tty_get(usize id); /** * @brief 获取tty的id - * - * @return usize + * + * @return usize */ usize tty_get_id(tty *__tty); @@ -121,6 +121,16 @@ void tty_set_framebuffer(tty *ttyx, framebuffer *fb); void tty_text_print(tty *ttyx, char *string, u32 color, u32 bgcolor); #define gen_color(r, g, b) (((r) << 16) | ((g) << 8) | (b)) +#define WHITE gen_color(0xee, 0xee, 0xee) +#define BLACK gen_color(0, 0, 0) +#define RED gen_color(0xee, 0x22, 0x22) +#define GREEN gen_color(0x22, 0xee, 0x22) +#define BLUE gen_color(0x22, 0x22, 0xee) +#define YELLOW gen_color(0xee, 0xee, 0x22) +#define ORANGE gen_color(0xee, 0xaa, 0x22) +#define PURPLE gen_color(0xee, 0, 0xee) +#define PINK gen_color(0xee, 0x44, 0x66) +#define GRAY gen_color(0xaa, 0xaa, 0xaa) usize tty_get_width(tty *ttyx); usize tty_get_height(tty *ttyx); @@ -132,8 +142,8 @@ bool tty_is_enabled(tty *ttyx); /** * @brief 打开某个tty - * - * @param ttyx + * + * @param ttyx * @return true 打开成功 * @return false 已经打开 * 或作为raw_framebuffer类型的tty,framebuffer已被其它raw_framebuffer diff --git a/src/kernel/tty/tty.rs b/src/kernel/tty/tty.rs index f817e51..3fe729e 100644 --- a/src/kernel/tty/tty.rs +++ b/src/kernel/tty/tty.rs @@ -150,10 +150,11 @@ impl Color { pub const RED: Color = Color(0xee, 0x22, 0x22); pub const GREEN: Color = Color(0x22, 0xee, 0x22); pub const BLUE: Color = Color(0x22, 0x22, 0xee); - pub const YELLOW: Color = Color(0xee, 0x22, 0x22); - pub const ORANGE: Color = Color(0xee, 0xee, 0x22); - pub const PURPLE: Color = Color(0xee, 0, 0xee); + pub const YELLOW: Color = Color(0xee, 0xee, 0x22); + pub const ORANGE: Color = Color(0xee, 0xaa, 0x22); + pub const PURPLE: Color = Color(0xee, 0x22, 0xee); pub const PINK: Color = Color(0xee, 0x44, 0x66); + pub const GRAY: Color = Color(0xaa, 0xaa, 0xaa); } impl From for u32 { From 4c923941eb9991b1ba21f83a72805b9295a5e4fd Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Thu, 7 Mar 2024 03:22:26 +0800 Subject: [PATCH 23/37] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtty=E5=9C=A8=E6=9C=89?= =?UTF-8?q?=E7=BC=A9=E6=94=BE=E6=97=B6=E6=8D=A2=E8=A1=8C=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kernel/tty/tty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kernel/tty/tty.c b/src/kernel/tty/tty.c index 2d63e9d..3530a47 100644 --- a/src/kernel/tty/tty.c +++ b/src/kernel/tty/tty.c @@ -58,8 +58,8 @@ void tty_set_framebuffer(tty *ttyx, framebuffer *fb) ttyx->height = ttyx->typeinfo.raw_framebuffer.height; if (ttyx->mode == tty_mode_text) { - ttyx->text.width = fb->width / tty_get_font()->char_width; - ttyx->text.height = fb->height / tty_get_font()->char_height; + ttyx->text.width = fb->width / (TTY_FONT_SCALE * tty_get_font()->char_width); + ttyx->text.height = fb->height / (TTY_FONT_SCALE * tty_get_font()->char_height); ttyx->text.line = 0; ttyx->text.column = 0; } From 5dc9de8195e316f43d785cc23bb4496cb7f9d470 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Thu, 7 Mar 2024 03:51:08 +0800 Subject: [PATCH 24/37] =?UTF-8?q?=E6=94=B9=E5=96=84=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E6=97=B6=E7=94=9F=E6=88=90=E9=AD=94=E6=95=B0=E7=9A=84=E6=97=B6?= =?UTF-8?q?=E9=97=B4=20=E6=9B=B4=E6=94=B9=E7=BC=96=E8=AF=91=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E8=84=9A=E6=9C=AC=E7=9A=84=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {src/scripts => scripts}/colorize | 0 {src/scripts => scripts}/depcheck | 0 scripts/magicgen | 7 +++++++ src/Makefile | 6 ++++-- 4 files changed, 11 insertions(+), 2 deletions(-) rename {src/scripts => scripts}/colorize (100%) rename {src/scripts => scripts}/depcheck (100%) create mode 100755 scripts/magicgen diff --git a/src/scripts/colorize b/scripts/colorize similarity index 100% rename from src/scripts/colorize rename to scripts/colorize diff --git a/src/scripts/depcheck b/scripts/depcheck similarity index 100% rename from src/scripts/depcheck rename to scripts/depcheck diff --git a/scripts/magicgen b/scripts/magicgen new file mode 100755 index 0000000..8b9d824 --- /dev/null +++ b/scripts/magicgen @@ -0,0 +1,7 @@ +#!/usr/bin/python + +import time + +curtime = str(int(time.time() * 1000)) + +print(curtime) diff --git a/src/Makefile b/src/Makefile index 7d5a4bb..7e15c45 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,7 @@ ARCH := $(shell uname -m) PWD := $(shell pwd) -SOURCE := ${PWD}/scripts +SOURCE := ${PWD}/../scripts ifeq (${ARCH},x86_64) ASM = nasm ASMFLAGS = -f elf64 @@ -12,7 +12,7 @@ ifdef release release = 1 endif -ALLOCATOR_MAGIC = $(shell doas hwclock | sha512sum | head -c 128 | md5sum | head -c 8) +ALLOCATOR_MAGIC = $(shell "${SOURCE}/magicgen" | sha512sum | head -c 128 | md5sum | head -c 8) SUBOBJS = kernel/kernel.o libk/libk.o rust.o @@ -58,6 +58,8 @@ metaverse.elf: kernel libk rust metaverse.lds .PHONY: kernel libk all clear postproc rust 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." postproc: @echo -n -e "\e[36m" From 9b9fcc87cf4fabc037470a078affcca61884b8bd Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Sat, 9 Mar 2024 16:59:54 +0800 Subject: [PATCH 25/37] =?UTF-8?q?tty=E4=BF=AE=E5=A4=8D\t\r=E7=AD=89?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E5=AD=97=E7=AC=A6=E5=85=89=E6=A0=87=E5=9B=BE?= =?UTF-8?q?=E5=83=8F=E6=AE=8B=E7=95=99=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kernel/tty/tty.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/kernel/tty/tty.c b/src/kernel/tty/tty.c index 3530a47..21e1418 100644 --- a/src/kernel/tty/tty.c +++ b/src/kernel/tty/tty.c @@ -175,17 +175,20 @@ void tty_text_print(tty *ttyx, char *string, u32 color, u32 bgcolor) } else if (c == '\t') { // 水平制表符 + putchar(ttyx, ' ', 0, 0); ttyx->text.column += 8; ttyx->text.column -= ttyx->text.column % 8; continue; } else if (c == '\r') { // 回到行首 + putchar(ttyx, ' ', 0, 0); ttyx->text.column = 0; continue; } else if (c == '\v') { // 垂直制表符 + putchar(ttyx, ' ', 0, 0); ttyx->text.line++; if (ttyx->text.line == ttyx->text.height) { From 38d65b4d7017764d2ed3777e7be5e3c267b14217 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Sat, 9 Mar 2024 18:28:45 +0800 Subject: [PATCH 26/37] =?UTF-8?q?=E8=A1=A5=E5=85=85=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E8=B0=83=E7=94=A8=E8=BF=94=E5=9B=9E=E5=80=BC=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E5=AF=84=E5=AD=98=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel/arch/x86_64/syscall.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/kernel/arch/x86_64/syscall.h b/include/kernel/arch/x86_64/syscall.h index 71f4e5c..107d5bd 100644 --- a/include/kernel/arch/x86_64/syscall.h +++ b/include/kernel/arch/x86_64/syscall.h @@ -24,6 +24,8 @@ extern void *system_calls_table[256]; * r14 - 参数7 * r15 - 参数8 * + * 返回值 - rax + * * 系统调用时,使用内核主堆栈。 */ From 933eaf3305aa937439b500848e3e31cb13b35985 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Sun, 10 Mar 2024 01:27:42 +0800 Subject: [PATCH 27/37] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=B8=AD=E6=96=AD?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E7=9A=84=E5=9F=BA=E6=9C=AC=E6=A1=86=E6=9E=B6?= =?UTF-8?q?=EF=BC=8C=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; + } +} From 0b8d6db7b78c2476321bfc594fcee7094d34c715 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Tue, 26 Mar 2024 03:27:00 +0800 Subject: [PATCH 28/37] =?UTF-8?q?=E5=9B=BA=E5=AE=9A=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E9=93=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rust-toolchain.toml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 rust-toolchain.toml diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..292fe49 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "stable" From 88acd1900fd3a098fbd455f442286e66fe287e57 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Thu, 4 Apr 2024 20:55:46 +0800 Subject: [PATCH 29/37] =?UTF-8?q?=E6=94=B9=E8=BF=9Bdepcheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/depcheck | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/scripts/depcheck b/scripts/depcheck index 9b20fda..295d7f1 100755 --- a/scripts/depcheck +++ b/scripts/depcheck @@ -49,15 +49,17 @@ for mod in kernel_modules: print(" " + color['lpink'] + f"{mod}" + color['reset'] + " exists.") else: print(" " + color['lred'] + f"{mod}" + color['reset'] + " not found.") - print("Kernel module " + - color['lred'] + f"{mod}" + color['reset'] + " is not installed.") + print( + "Kernel module " + + color['lred'] + f"{mod}" + color['reset'] + " is not installed.") exit(-1) # 检查软件依赖 pathsenv = os.environ.get("PATH").split(":") for software, progs in softwares.items(): - print("Checking " + color['lcyan'] + - f"{software}" + color['reset'] + " ...") + print( + "Checking " + color['lcyan'] + + f"{software}" + color['reset'] + " ...") for program in progs: exists = False for path in pathsenv: @@ -65,15 +67,19 @@ for software, progs in softwares.items(): exists = True break if exists: - print(" " + color['lyellow'] + - f"{program}" + color['reset'] + " existed.") + print( + " " + color['lyellow'] + + f"{program}" + color['reset'] + " existed.") else: - print(" " + color['lred'] + - f"{program}" + color['reset'] + " not found.") + print( + " " + color['lred'] + + f"{program}" + color['reset'] + " not found.") - print("Software " + color['lred'] + f"{software}" + - color['reset'] + " is not installed or completed.") + print( + "Software " + color['lred'] + f"{software}" + + color['reset'] + " is not installed or completed.") exit(-2) -print("All dependencies are " + - color['lgreen'] + "satisfied." + color['reset']) +print( + "All dependencies are " + + color['lgreen'] + "satisfied." + color['reset']) From bec4634857fd691f3a954c86db9725fd7b132e48 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Thu, 4 Apr 2024 21:38:44 +0800 Subject: [PATCH 30/37] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AE=89=E8=A3=85?= =?UTF-8?q?=E8=87=B3=E7=B3=BB=E7=BB=9Fgrub=E7=9A=84=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 3316f1c..1145cd8 100644 --- a/Makefile +++ b/Makefile @@ -1,20 +1,20 @@ -SOURCE := $(shell pwd)/src/scripts +SOURCE := $(shell pwd)/scripts -.PHONY: all clear run debug config disass +.PHONY: all clear run debug disass -all: config +all: metaverse_kernel @make -C src all --no-print-directory -clear: config +clear: metaverse_kernel @make -C src clear --no-print-directory -run: config +run: metaverse_kernel @make -C test run --no-print-directory -debug: config +debug: metaverse_kernel @make -C test debug --no-print-directory -config: +metaverse_kernel: @if [ "${shell uname -s}" != "Linux" ]; then \ echo -e "\e[1;33mMetaverse\e[0m must build under \e[1;35mLinux\e[0m or itself."; \ exit -1; \ @@ -22,9 +22,28 @@ config: @if [ -f "metaverse_kernel" ]; then \ echo; \ else \ - touch metaverse_kernel; \ "${SOURCE}/depcheck"; \ + if [ $$? != 0 ]; then \ + exit $$?; \ + fi; \ + touch metaverse_kernel; \ + fi + @if [ $$? != 0 ]; then \ + exit -1; \ fi disass: objdump -D src/metaverse.elf > kerndisass.txt + +install-grub: + @cp src/metaverse.elf /boot/ + @if ! grep -q "Metaverse" /boot/grub/grub.cfg; then \ + echo -e 'menuentry "Metaverse" {\n set root=(hd0,gpt1)\n multiboot2 /metaverse.elf\n}\n' >> \ + /boot/grub/grub.cfg; \ + echo -e 'Added Metaverse into grub entries.'; \ + else \ + echo -e 'Metaverse entry exists.'; \ + fi + +remove-grub: + @-rm /boot/metaverse.elf From 37ee2ca85d0534d3cadfdf412f1233b52f1425fe Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Thu, 4 Apr 2024 22:47:42 +0800 Subject: [PATCH 31/37] =?UTF-8?q?=E5=9C=A8=E8=AE=BE=E7=BD=AE=E4=B8=AD?= =?UTF-8?q?=E6=96=AD=E4=B9=8B=E5=89=8D=E5=B0=86=E6=89=80=E6=9C=89=E7=9A=84?= =?UTF-8?q?=E4=B8=AD=E6=96=AD=E6=8F=8F=E8=BF=B0=E7=AC=A6=E5=AE=9A=E5=90=91?= =?UTF-8?q?=E5=88=B0unsupported=E5=A4=84=E7=90=86=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kernel/arch/x86_64/interrupt_x86_64.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/kernel/arch/x86_64/interrupt_x86_64.c b/src/kernel/arch/x86_64/interrupt_x86_64.c index 98f7b00..6879f22 100644 --- a/src/kernel/arch/x86_64/interrupt_x86_64.c +++ b/src/kernel/arch/x86_64/interrupt_x86_64.c @@ -4,8 +4,14 @@ #include void interrupt_init() -{ +{ gate_descriptor_t gate; + trap_gate_generate(gate, interrupt_entry_sym(UNSUPPORTED)); + for (usize i = 4; i < 256; i++) + { + interrupt_register_gate(gate, i); + } + trap_gate_generate(gate, interrupt_entry_sym(DE)); interrupt_register_gate(gate, 0); trap_gate_generate(gate, interrupt_entry_sym(UNSUPPORTED)); @@ -14,5 +20,6 @@ void interrupt_init() interrupt_register_gate(gate, 2); trap_gate_generate(gate, interrupt_entry_sym(BP)); interrupt_register_gate(gate, 3); + interrupt_open(); } From 341ca618dea4ece0fdf981cb679892aa33d74a52 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Thu, 4 Apr 2024 22:48:38 +0800 Subject: [PATCH 32/37] =?UTF-8?q?=E5=BC=95=E5=85=A5=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E6=8A=98=E4=B8=AD=E7=9A=84=E4=B8=8D=E5=AE=9A=E5=8F=82=E6=96=B9?= =?UTF-8?q?=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/utils.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/include/utils.h b/include/utils.h index 5564fa9..22d08a3 100644 --- a/include/utils.h +++ b/include/utils.h @@ -8,6 +8,20 @@ #define into_bytes(addr) ((u8 *)(addr)) #define bytes_into(bytes, type) ((type *)(bytes)) -void pointer_to_string(u64 addr, char * dest); +void pointer_to_string(u64 addr, char *dest); + +typedef struct __va_args +{ + usize length; + void *args[0]; +} va_args; + +#define va_args_gen(result, length) \ + void *__reserved__[length]; \ + va_args __va_args__; \ + result = &__va_args__; + +#define va_args_set(vaargs, index, val) \ + vaargs->args[index] = &val; #endif From 8d4938c7ba9e8c843bf74eae445a93b23491cecf Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Fri, 5 Apr 2024 22:46:35 +0800 Subject: [PATCH 33/37] =?UTF-8?q?=E6=9B=B4=E6=96=B0rust=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rustlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rustlib b/rustlib index 087c479..603b446 160000 --- a/rustlib +++ b/rustlib @@ -1 +1 @@ -Subproject commit 087c4795bbc23cd0baee060bda8c1159a971a542 +Subproject commit 603b446b09569e22e6b939bf173a518c0955d687 From b0b790fab82526264466ff923a097dfc74390e86 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Fri, 5 Apr 2024 22:58:19 +0800 Subject: [PATCH 34/37] =?UTF-8?q?=E6=94=B9=E8=BF=9Brustlib=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rustlib | 2 +- src/Makefile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rustlib b/rustlib index 603b446..6a2ca2a 160000 --- a/rustlib +++ b/rustlib @@ -1 +1 @@ -Subproject commit 603b446b09569e22e6b939bf173a518c0955d687 +Subproject commit 6a2ca2afcd651e46f1c19f8d8a3f685fd982d824 diff --git a/src/Makefile b/src/Makefile index 94ca7a6..24a0b66 100644 --- a/src/Makefile +++ b/src/Makefile @@ -30,7 +30,7 @@ endif RSCFLAGS = --emit obj --crate-type staticlib --verbose \ --crate-name=metaverse \ --edition 2021 \ - -L crate="${PWD}/../rustlib/${ARCH}/src/" \ + -L crate="${PWD}/../rustlib/src/" \ -C code-model=large \ -C relocation-model=static \ -C embed-bitcode=no @@ -47,7 +47,7 @@ ifeq (${ARCH},x86_64) RSCFLAGS := ${RSCFLAGS} -C target-feature=-sse endif -RUSTLIB_PATH = ../rustlib/${ARCH}/lib +RUSTLIB_PATH = ../rustlib/${ARCH} RUST_LIBS = "${RUSTLIB_PATH}/liballoc.rlib" "${RUSTLIB_PATH}/libcompiler_builtins.rlib" \ "${RUSTLIB_PATH}/libcore.rlib" "${RUSTLIB_PATH}/librustc_std_workspace_core.rlib" From 00d655c4687572445510eb9781c863fd1baa69a0 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Sat, 6 Apr 2024 04:07:32 +0800 Subject: [PATCH 35/37] =?UTF-8?q?=E9=87=8D=E6=9E=84C=E8=AF=AD=E8=A8=80?= =?UTF-8?q?=E9=83=A8=E5=88=86=E7=9A=84=E5=86=85=E5=AD=98=E5=88=86=E9=85=8D?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 1 + include/kernel/arch/x86_64/memm.h | 2 + include/kernel/memm.h | 104 +-------------- include/kernel/memm/allocator/raw.h | 2 - src/kernel/arch/x86_64/memm_x86_64.c | 25 +--- src/kernel/memm/memm.c | 192 ++------------------------- 6 files changed, 30 insertions(+), 296 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d2d3873..44bc550 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ name = "metaverse" version = "0.1.0" edition = "2021" +crate-type = ["staticlib"] # 此Cargo.toml仅用于rust-analyzer识别rust部分的代码 # 不应使用cargo编译 diff --git a/include/kernel/arch/x86_64/memm.h b/include/kernel/arch/x86_64/memm.h index 1fc1d31..98664b4 100644 --- a/include/kernel/arch/x86_64/memm.h +++ b/include/kernel/arch/x86_64/memm.h @@ -29,6 +29,8 @@ */ #define MEMM_PAGE_SIZE 4096 +#define MEMM_PAGE_TABLE_SIZE 4096 + typedef enum __memm_page_size { MEMM_PAGE_SIZE_4K = 1, // 1个4KB页大小 diff --git a/include/kernel/memm.h b/include/kernel/memm.h index 2ba8920..9d561b4 100644 --- a/include/kernel/memm.h +++ b/include/kernel/memm.h @@ -24,11 +24,13 @@ /** * @name MEMM_ALLOC_ONLY_MEMORY * - * 只分配不映射空间,暂时为固定值`128MB`。物理地址`0`\~`MEMM_ALLOC_ONLY_MEMORY`的空间在进入内核前已经映射至内核空间。 + * 只分配不映射空间,暂时为固定值`64MB`。物理地址`0`\~`MEMM_ALLOC_ONLY_MEMORY`的空间在进入内核前已经映射至内核空间。 * * 这段内存空间包含**1MB以内低地址**、**内核镜像**以及未分配空间,未分配空间被一个分配器独占。 */ -#define MEMM_ALLOC_ONLY_MEMORY (128 * 1024 * 1024) +#define MEMM_ALLOC_ONLY_MEMORY (64 * 1024 * 1024) + +#define MEMM_PAGE_TABLE_AREA_MAX (4 * 1024 * 1024) /** * @name memm_allocate_t, memm_free_t @@ -126,10 +128,6 @@ typedef struct __allocator_t // 调用分配器的`free`方法时设为`false`。 bool full; - // 进程标志服,表示此分配器所属的进程,为0代表属于内核。 - usize pid; - // 若分配器不属于内核,此成员储存此分配器的用户空间地址。 - void *userspace; // 分配器类型。在目录`include/kernel/memm/allocator`中对每个分配器分别定义一个唯一值。 usize type; usize size; @@ -144,75 +142,23 @@ typedef struct __allocator_t u64 allocator_instance[0]; } allocator_t; -typedef struct __allocator_iterator_t -{ - allocator_t *allocator; - struct __allocator_iterator_t *left, *right; -} allocator_iterator_t; - /** * @name 内存管理器 * * @internal alloc_only_memory * * 在进入内核主程序之前,有些不在内核中的虚拟内存空间已经被页表映射,这部分内存不可以再映射到物理页框。 - * - * @internal mapped_page_amount - * - * 已经映射的页数量。若不是最小的页会被视作多个最小页计数。 - * - * @internal mapped_4k_page, mapped_2m_page, mapped_1g_page - * @addindex 平台依赖宏 x86_64 - * - * 分别记录已经映射的三种大小页的数量。 - * - * @internal page_map - * - * 页地图,每个bit表示对应的最小页是否被映射。 - * - * @internal allocator_map - * - * 分配器地图。每个bit表示对应的最小页是否被一个分配器控制。 - * - * @internal destructed_allocator_map - * - * 释放的分配器页地图。每个bit表示对应的最小页是否曾经被分配器控制并且现在控制这个页的分配器已经释放。 - * - * 值为1的bit位对应的最小页可以直接**取消映射**、**重新构造一个分配器**、**加载可执行程序**等。 - * - * @internal available_pages_table - * - * 空闲页线段搜索表。 - * - * @internal allocators - * - * 分配器二叉树。 */ typedef struct __mem_manager_t { usize memory_size; usize page_amount; - // 在进入内核主程序之前,有些不在内核中的虚拟内存空间已经被页表映射,这部分内存不可以再映射到物理页框 usize alloc_only_memory; - // 已经映射的页数量。若不是最小的页会被视作多个最小页计数。 - usize mapped_page_amount; - memm_page_counter platformed_page_counter; + allocator_t *kernel_base_allocator; - // 页地图。每个bit都表示这个页是否被映射。 - u8 *page_map; - // 分配器页地图。每个bit表示这个页是否被内存分配器控制。 - u8 *allocator_map; - // 释放的分配器页地图。每个bit表示这个页是否曾经被内存分配器控制且现在被释放。 - // 值为1的bit位对应的最小页可以直接**取消映射**、**重新构造一个分配器**、**加载可执行程序**等。 - u8 *destructed_allocator_map; - - // 空闲页线段搜索表 - lst_iterator_t *available_pages_table; - - // 分配器二叉树 - allocator_iterator_t *allocators; + usize page_table_area; } memory_manager_t; /** @@ -261,23 +207,6 @@ allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid */ void memm_allocator_destruct(allocator_t *allocator); -/** - * @name memm_allocate - * - * ```c - * void *memm_allocate(usize size, usize pid); - * ``` - * - * 申请内存。`pid`为0时为内核分配。 - * - * 所有内存在内核空间都有对物理内存空间的直接映射。 - */ -void *memm_allocate(usize size, usize pid); -#define memm_addr_set_allocator(mem, allocator) \ - *(allocator_t **)((void *)(mem)-16) = allocator; -#define memm_addr_get_allocator(mem) \ - ((*(allocator_t **)((void *)(mem)-16))) - /** * @name memm_kernel_allocate * @@ -289,17 +218,6 @@ void *memm_allocate(usize size, usize pid); */ void *memm_kernel_allocate(usize size); -/** - * @name memm_user_allocate - * - * ```c - * void *memm_user_allocate(usize size, usize pid); - * ``` - * - * 为用户空间申请内存。 - */ -void *memm_user_allocate(usize size, usize pid); - /** * @name memm_free * @@ -311,14 +229,6 @@ void *memm_user_allocate(usize size, usize pid); */ void memm_free(void *mem); -/** - * @name find_fitable_pages - * - * ```c - * usize find_fitable_pages(usize page_count); - * ``` - * 寻找大小合适的一组连续页 - */ -usize find_fitable_pages(usize page_count); +void *memm_allcate_pagetable(); #endif diff --git a/include/kernel/memm/allocator/raw.h b/include/kernel/memm/allocator/raw.h index d9d1258..4b1741c 100644 --- a/include/kernel/memm/allocator/raw.h +++ b/include/kernel/memm/allocator/raw.h @@ -10,8 +10,6 @@ typedef struct __raw_allocator_cell { usize capacity; // 是content的长度 usize length; // 是实际使用的长度 - allocator_t *allocator; // 所在的分配器 - usize reserved; u8 content[0]; } raw_allocator_cell; #define raw_allocator_next_cell(cell) (raw_allocator_cell *)((void *)((cell)->content) + (cell)->capacity) diff --git a/src/kernel/arch/x86_64/memm_x86_64.c b/src/kernel/arch/x86_64/memm_x86_64.c index e924ab6..913e919 100644 --- a/src/kernel/arch/x86_64/memm_x86_64.c +++ b/src/kernel/arch/x86_64/memm_x86_64.c @@ -9,8 +9,9 @@ map_pageframe_to((u64)addr, (u64)addr, false, true, MEMM_PAGE_SIZE_4K); // 这里的physical必须保证根据ps对齐 -static void map_pageframe_to(u64 target, u64 physical, - bool user, bool write, memm_page_size ps) +static void map_pageframe_to( + u64 target, u64 physical, + bool user, bool write, memm_page_size ps) { if (!is_cannonical(target)) return; @@ -22,7 +23,7 @@ static void map_pageframe_to(u64 target, u64 physical, PDPT = (u64 *)memm_entry_get_address(pml4e); else { - PDPT = (u64 *)(find_fitable_pages(1) * MEMM_PAGE_SIZE); + PDPT = memm_allcate_pagetable(); map_pagemap(PDPT); memset(PDPT, 0, MEMM_PAGE_SIZE); @@ -50,7 +51,7 @@ static void map_pageframe_to(u64 target, u64 physical, PDT = (u64 *)memm_entry_get_address(pdpte); else { - PDT = (u64 *)(find_fitable_pages(1) * MEMM_PAGE_SIZE); + PDT = memm_allcate_pagetable(); map_pagemap(PDT); memset(PDT, 0, MEMM_PAGE_SIZE); @@ -78,7 +79,7 @@ static void map_pageframe_to(u64 target, u64 physical, PT = (u64 *)memm_entry_get_address(pde); else { - PT = (u64 *)(find_fitable_pages(1) * MEMM_PAGE_SIZE); + PT = memm_allcate_pagetable(); map_pagemap(PT); memset(PT, 0, MEMM_PAGE_SIZE); @@ -122,20 +123,6 @@ bool memm_map_pageframes_to( align = MEMM_4K_ALIGN_MASK + 1; } align /= MEMM_PAGE_SIZE; - memory_manager_t *mm = memm_get_manager(); - switch (align) - { - case MEMM_PAGE_SIZE_4K: - mm->platformed_page_counter.mapped_4k_page++; - case MEMM_PAGE_SIZE_2M: - mm->platformed_page_counter.mapped_2m_page++; - case MEMM_PAGE_SIZE_1G: - mm->platformed_page_counter.mapped_1g_page++; - } - for (usize i = physical / MEMM_PAGE_SIZE; i < physical / MEMM_PAGE_SIZE + align; i++) - { - bitmap_set(mm->page_map, i); - } map_pageframe_to(target, physical, user, write, align); diff --git a/src/kernel/memm/memm.c b/src/kernel/memm/memm.c index 34898c5..c2ae788 100644 --- a/src/kernel/memm/memm.c +++ b/src/kernel/memm/memm.c @@ -17,54 +17,12 @@ memory_manager_t *memm_new(usize mem_size) usize kernel_initial_size = (usize)&kend; align_to(kernel_initial_size, MEMM_PAGE_SIZE); - // 配置分配器树 allocator_t *allocator0 = memm_allocator_new( (void *)kernel_initial_size, - memory_manager.alloc_only_memory - kernel_initial_size, + memory_manager.alloc_only_memory - MEMM_PAGE_TABLE_AREA_MAX - kernel_initial_size, MEMM_RAW_ALLOCATOR, 0); - allocator_iterator_t *alcatr_ind = allocator0->allocate( - &allocator0->allocator_instance, sizeof(allocator_iterator_t)); - - alcatr_ind->allocator = allocator0; - alcatr_ind->left = nullptr; - alcatr_ind->right = nullptr; - - memory_manager.allocators = alcatr_ind; - - // 配置页映射地图 - usize pmc_size = memory_manager.page_amount; - align_to(pmc_size, 8); - pmc_size /= 8; - - memory_manager.page_map = allocator0->allocate(&allocator0->allocator_instance, pmc_size); - memset(memory_manager.page_map, 0, pmc_size); - memset(memory_manager.page_map, 0xff, MEMM_ALLOC_ONLY_MEMORY / MEMM_PAGE_SIZE / 8); - for (usize i = (MEMM_ALLOC_ONLY_MEMORY / MEMM_PAGE_SIZE / 8) * (u8)8; - i < MEMM_ALLOC_ONLY_MEMORY / MEMM_PAGE_SIZE % 8; i++) - { - bitmap_set(memory_manager.page_map, i); - } - - // 配置分配器页地图 - memory_manager.allocator_map = - allocator0->allocate(&allocator0->allocator_instance, pmc_size); - memset(memory_manager.allocator_map, 0, pmc_size); - for (usize i = kernel_initial_size / MEMM_PAGE_SIZE; - i < MEMM_ALLOC_ONLY_MEMORY / MEMM_PAGE_SIZE; - i += MEMM_PAGE_SIZE) - { - bitmap_set(memory_manager.allocator_map, i); - } - - // 分配器释放页地图 - memory_manager.destructed_allocator_map = - allocator0->allocate(&allocator0->allocator_instance, pmc_size); - memset(memory_manager.destructed_allocator_map, 0, pmc_size); - - // 配置空闲页线段搜索表 - memory_manager.available_pages_table = lst_new(0, memory_manager.page_amount); - lst_remove(memory_manager.available_pages_table, 0, MEMM_ALLOC_ONLY_MEMORY / MEMM_PAGE_SIZE, false); + memory_manager.kernel_base_allocator = allocator0; return &memory_manager; } @@ -102,129 +60,15 @@ void memm_allocator_destruct(allocator_t *allocator) KERNEL_TODO(); } -void *memm_find_and_allocate(allocator_iterator_t *allocator_ind, usize size, usize pid, allocator_t **writeback) -{ - void *ptr; - allocator_t *allocator = allocator_ind->allocator; - if (allocator->pid == pid && allocator->full == false) - { // 尝试用本节点分配 - if ((ptr = allocator->allocate(&allocator->allocator_instance, size)) != nullptr) - { - *writeback = allocator; - return ptr; - } - else - { - if ((ptr = allocator->allocate(&allocator->allocator_instance, 0)) == nullptr) - allocator->full = true; - } - } - if (allocator_ind->left != nullptr) - { // 尝试用左子树分配 - ptr = memm_find_and_allocate(allocator_ind->left, size, pid, writeback); - if (ptr != nullptr) - return ptr; - } - if (allocator_ind->right != nullptr) - { // 尝试用右子树分配 - ptr = memm_find_and_allocate(allocator_ind->right, size, pid, writeback); - if (ptr != nullptr) - return ptr; - } - // 都不行就只能返回nullptr - return nullptr; -} - -static void insert_allocator(allocator_iterator_t *iter, allocator_iterator_t *inserter) -{ - if (inserter->allocator < iter->allocator) - { - if (iter->left == nullptr) - { - iter->left = inserter; - return; - } - else - { - insert_allocator(iter->left, inserter); - } - } - else if (inserter->allocator > iter->allocator) - { - if (iter->right == nullptr) - { - iter->right = inserter; - return; - } - else - { - insert_allocator(iter->right, inserter); - } - } -} - -void *memm_allocate(usize size, usize pid) -{ - usize orgsize = size; - // 从分配器树中分配内存 - allocator_t *allocator; - void *ptr = memm_find_and_allocate(memory_manager.allocators, size, pid, &allocator); - if (ptr != nullptr) - goto after_allocation; - - // 分配器树中没有可分配的内存 - size += sizeof(allocator_t) + MEMM_PAGE_SIZE; - align_to(size, MEMM_PAGE_SIZE); - size /= MEMM_PAGE_SIZE; - usize allocator_start = find_fitable_pages(size); - if (allocator_start == 0) - return nullptr; // 内存中已经没有可分配的页了 - for (usize i = allocator_start; i < allocator_start + size; i++) - { - bitmap_set(memory_manager.allocator_map, i); - } - memm_map_pageframes_to( - allocator_start * MEMM_PAGE_SIZE, allocator_start * MEMM_PAGE_SIZE, - size * MEMM_PAGE_SIZE, - false, // 用户空间标志 - true // 写权限 - ); - - // 在新映射的页中创建一个分配器 - // TODO 在用户态可能需要实现一个效率更高的分配器 - allocator_t *new_allocator = - memm_allocator_new((void *)(allocator_start * MEMM_PAGE_SIZE), size * MEMM_PAGE_SIZE, - MEMM_RAW_ALLOCATOR, pid); - allocator = new_allocator; - - allocator_iterator_t *allind = memm_kernel_allocate(sizeof(allocator_iterator_t)); - allind->allocator = new_allocator; - allind->left = nullptr; - allind->right = nullptr; - insert_allocator(memory_manager.allocators, allind); - ptr = new_allocator->allocate(&new_allocator->allocator_instance, orgsize); - -after_allocation: - if (ptr != nullptr) - memm_addr_set_allocator(ptr, allocator); - return ptr; -} - void *memm_kernel_allocate(usize size) { - return memm_allocate(size, 0); -} - -void *memm_user_allocate(usize size, usize pid) -{ - void *res = memm_allocate(size, pid); - // TODO 将内存空间映射到用户空间 - return res; + allocator_t *allocator = memory_manager.kernel_base_allocator; + return allocator->allocate(allocator->allocator_instance, size); } void memm_free(void *mem) { - allocator_t *allocator = memm_addr_get_allocator(mem); + allocator_t *allocator = memory_manager.kernel_base_allocator; if (allocator->magic != MEMM_ALLOCATOR_MAGIC) return; if (is_user_address((u64)mem)) @@ -236,23 +80,15 @@ void memm_free(void *mem) allocator->full = false; } -usize find_fitable_pages(usize page_count) +void *memm_allcate_pagetable() { - usize res = 0; - lst_iterator_t *iter = memory_manager.available_pages_table; - do + if (memory_manager.page_table_area < MEMM_PAGE_TABLE_AREA_MAX) { - if (iter->line.right - iter->line.left > page_count) - { - res = iter->line.left; - lst_remove(iter, res, res + page_count, false); - for (usize i = res; i < res + page_count; i++) - { - bitmap_set(memory_manager.page_map, i); - } - break; - } - } while ((iter = lst_next(iter)) != nullptr); - memory_manager.mapped_page_amount += page_count; - return res; + memory_manager.page_table_area += MEMM_PAGE_TABLE_SIZE; + return memory_manager.alloc_only_memory - memory_manager.page_table_area; + } + else + { + // TODO + } } From 22781004d08cf17c8536ffec319aa11b37d1c3ca Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Sat, 6 Apr 2024 04:13:51 +0800 Subject: [PATCH 36/37] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=8D=E5=BF=85?= =?UTF-8?q?=E8=A6=81=E7=9A=84make=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Makefile | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Makefile b/src/Makefile index 24a0b66..ffbdcc9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -37,16 +37,13 @@ RSCFLAGS = --emit obj --crate-type staticlib --verbose \ ifeq (${ARCH},x86_64) RSCFLAGS := ${RSCFLAGS} --target x86_64-unknown-none + RSCFLAGS := ${RSCFLAGS} -C target-feature=-sse endif ifdef release RSCFLAGS := ${RSCFLAGS} -O endif -ifeq (${ARCH},x86_64) - RSCFLAGS := ${RSCFLAGS} -C target-feature=-sse -endif - RUSTLIB_PATH = ../rustlib/${ARCH} RUST_LIBS = "${RUSTLIB_PATH}/liballoc.rlib" "${RUSTLIB_PATH}/libcompiler_builtins.rlib" \ "${RUSTLIB_PATH}/libcore.rlib" "${RUSTLIB_PATH}/librustc_std_workspace_core.rlib" From 8f82c88e30e28e6f7907a7203a2bd3b7126416e5 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Sat, 6 Apr 2024 04:17:44 +0800 Subject: [PATCH 37/37] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E6=9E=84=E5=BB=BA=E7=9A=84=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 1145cd8..64f711c 100644 --- a/Makefile +++ b/Makefile @@ -19,18 +19,11 @@ metaverse_kernel: echo -e "\e[1;33mMetaverse\e[0m must build under \e[1;35mLinux\e[0m or itself."; \ exit -1; \ fi - @if [ -f "metaverse_kernel" ]; then \ - echo; \ - else \ - "${SOURCE}/depcheck"; \ - if [ $$? != 0 ]; then \ - exit $$?; \ - fi; \ - touch metaverse_kernel; \ - fi + @"${SOURCE}/depcheck"; @if [ $$? != 0 ]; then \ - exit -1; \ + exit $$?; \ fi + @touch metaverse_kernel disass: objdump -D src/metaverse.elf > kerndisass.txt