Compare commits

...

17 Commits

Author SHA1 Message Date
pointer-to-bios 46b80996f7 将rustlib引用的url切换到github 2024-04-07 05:13:18 +08:00
pointer-to-bios 77b8b4cd7c 更新rust core crate 2024-04-07 05:10:42 +08:00
pointer-to-bios ad8cb92e78 解决内存管理重构后的一些bug 2024-04-06 18:07:00 +08:00
pointer-to-bios 327c10963c
Merge pull request #2 from pointertobios/main
重构内存分配器、增加中断支持、整理rust运行时环境
2024-04-06 04:27:37 +08:00
pointer-to-bios 8f82c88e30 改进初始化构建的脚本 2024-04-06 04:17:44 +08:00
pointer-to-bios 22781004d0 优化不必要的make脚本 2024-04-06 04:13:51 +08:00
pointer-to-bios 00d655c468 重构C语言部分的内存分配器 2024-04-06 04:07:32 +08:00
pointer-to-bios b0b790fab8 改进rustlib目录结构 2024-04-05 22:58:19 +08:00
pointer-to-bios 8d4938c7ba 更新rust版本 2024-04-05 22:46:35 +08:00
pointer-to-bios 341ca618de 引入一个折中的不定参方案 2024-04-04 22:48:38 +08:00
pointer-to-bios 37ee2ca85d 在设置中断之前将所有的中断描述符定向到unsupported处理函数 2024-04-04 22:47:42 +08:00
pointer-to-bios bec4634857 增加安装至系统grub的选项 2024-04-04 21:38:44 +08:00
pointer-to-bios 88acd1900f 改进depcheck 2024-04-04 20:55:46 +08:00
pointer-to-bios 0b8d6db7b7 固定工具链 2024-03-26 03:27:00 +08:00
pointer-to-bios 933eaf3305 完成中断管理的基本框架,增加BUILD_ID 2024-03-10 01:27:42 +08:00
pointer-to-bios 38d65b4d70 补充系统调用返回值使用的寄存器 2024-03-09 18:28:45 +08:00
pointer-to-bios 9b9fcc87cf tty修复\t\r等控制字符光标图像残留的问题 2024-03-09 16:59:54 +08:00
34 changed files with 703 additions and 355 deletions

2
.gitmodules vendored
View File

@ -1,3 +1,3 @@
[submodule "rustlib"]
path = rustlib
url = http://git.suthby.org:2024/metaverse/rustenv
url = https://github.com/metaverse-kernel/rustenv.git

View File

@ -3,6 +3,9 @@ name = "metaverse"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["staticlib"]
# 此Cargo.toml仅用于rust-analyzer识别rust部分的代码
# 不应使用cargo编译

View File

@ -1,30 +1,42 @@
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; \
fi
@if [ -f "metaverse_kernel" ]; then \
echo; \
else \
touch metaverse_kernel; \
"${SOURCE}/depcheck"; \
@"${SOURCE}/depcheck";
@if [ $$? != 0 ]; then \
exit $$?; \
fi
@touch metaverse_kernel
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

View File

@ -41,4 +41,29 @@ typedef struct __gate_descriptor_t
*/
extern gate_descriptor_t idt[256];
#define interrupt_gate_generate(desc, addr) \
{ \
(desc).segment_selector = 0x8; \
(desc).flags = INTERRUPT_DESCRIPTOR_FLAG_TYPE_INTERRUPT | \
INTERRUPT_DESCRIPTOR_FLAG_IST; \
(desc).reserved = 0; \
(desc).offset_01 = (u16)((u64)(addr)); \
(desc).offset_23 = (u16)(((u64)(addr)) >> 16); \
(desc).offset_4567 = (u32)(((u64)(addr)) >> 32); \
}
#define trap_gate_generate(desc, addr) \
{ \
(desc).segment_selector = 0x8; \
(desc).flags = INTERRUPT_DESCRIPTOR_FLAG_TYPE_TRAP | \
INTERRUPT_DESCRIPTOR_FLAG_IST; \
(desc).reserved = 0; \
(desc).offset_01 = (u16)((u64)(addr)); \
(desc).offset_23 = (u16)(((u64)(addr)) >> 16); \
(desc).offset_4567 = (u32)(((u64)(addr)) >> 32); \
}
#define interrupt_register_gate(desc, index) \
idt[index] = desc;
#endif

View File

@ -0,0 +1,87 @@
#ifndef X86_64_INTERRUPT_PROCS_H
#define X86_64_INTERRUPT_PROCS_H 1
#include <utils.h>
/**
* @name interrupt_entry
* @addindex x86_64
*
*
*
* ```c
* void interrupt_entry();
* ```
*
* ```asm
* interrupt_entry_xx:
* ;
* interrupt_entry_enter
*
* ;
* ...
*
* ;
* interrupt_entry_leave
* iret
* ```
*/
typedef void (*interrupt_entry)();
/**
* @name interrupt_entry_gen
* @addindex x86_64
*
*
*
* ```c
* #define interrupt_entry_gen(interrupt)
* ```
*/
#define interrupt_entry_gen(interrupt) \
extern void interrupt_entry_##interrupt()
#define interrupt_entry_sym(interrupt) \
interrupt_entry_##interrupt
/**
* @name interrupt_request
* @addindex
*
*
*
* ```c
* void interrupt_request(u64 rip, u64 rsp);
* ```
*
*
*/
typedef void (*interrupt_request)(u64 rip, u64 rsp, u64 errcode);
/**
* @name interrupt_req_gen
* @addindex x86_64
*
*
*
* ```c
* #define interrupt_req_gen(interrupt)
* ```
*/
#define interrupt_req_gen(interrupt) \
void interrupt_req_##interrupt(u64 rip, u64 rsp, u64 errcode)
#define interrupt_req_sym(interrupt) \
interrupt_req_##interrupt
#define UNSUPPORTED
#define DE
#define NMI
#define BP
interrupt_entry_gen(UNSUPPORTED);
interrupt_entry_gen(DE);
interrupt_entry_gen(NMI);
interrupt_entry_gen(BP);
#endif

View File

@ -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页大小

View File

@ -0,0 +1,25 @@
#ifndef X86_64_PROC_H
#define X86_64_PROC_H 1
#include <types.h>
/**
* @name proc_texture_registers_t
* @addindex x86_64
*
*
*/
typedef struct __proc_texture_registers_t
{
u16 es, ds;
u32 reserved;
u64 r15, r14, r13, r12;
u64 r11, r10, r9, r8;
u64 rdi, rsi, rdx, rbx, rcx, rax;
u64 rbp;
u64 rip, cs;
u64 rflags;
u64 rsp, ss;
} proc_texture_registers_t;
#endif

View File

@ -24,6 +24,8 @@ extern void *system_calls_table[256];
* r14 - 7
* r15 - 8
*
* - rax
*
* 使
*/

View File

@ -1,6 +1,11 @@
#ifndef INTERRUPT_H
#define INTERRUPT_H 1
#ifdef __x86_64__
#include <kernel/arch/x86_64/interrupt.h>
#endif
/**
* @name interrupt_open
* @addindex
@ -25,4 +30,16 @@ void interrupt_open();
*/
void interrupt_close();
/**
* @name interrupt_init
* @addindex
*
* ```c
* void interrupt_init();
* ```
*
*
*/
void interrupt_init();
#endif

View File

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

View File

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

View File

@ -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表示对应的最小页是否曾经被分配器控制并且现在控制这个页的分配器已经释放
*
* 1bit位对应的最小页可以直接************
*
* @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

View File

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

View File

@ -5,4 +5,23 @@
#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);
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

2
rust-toolchain.toml Normal file
View File

@ -0,0 +1,2 @@
[toolchain]
channel = "stable"

@ -1 +1 @@
Subproject commit 087c4795bbc23cd0baee060bda8c1159a971a542
Subproject commit bb4a5d1b55c36070d629400bddd6d267d2f0714a

View File

@ -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'])

View File

@ -14,9 +14,12 @@ endif
ALLOCATOR_MAGIC = $(shell "${SOURCE}/magicgen" | sha512sum | head -c 128 | md5sum | head -c 8)
BUILD_ID = $(shell "${SOURCE}/magicgen" | sha512sum | head -c 128 | md5sum | head -c 4)
SUBOBJS = kernel/kernel.o libk/libk.o rust.o
DEFINES = ARCH="${ARCH}" ASM="${ASM}" ASMFLAGS="${ASMFLAGS}" SOURCE="${SOURCE}" PWD="${PWD}" ALLOCATOR_MAGIC="${ALLOCATOR_MAGIC}"
DEFINES = ARCH="${ARCH}" ASM="${ASM}" ASMFLAGS="${ASMFLAGS}" SOURCE="${SOURCE}" PWD="${PWD}" \
ALLOCATOR_MAGIC="${ALLOCATOR_MAGIC}" BUILD_ID="${BUILD_ID}"
ifdef release
DEFINES := ${DEFINES} release=1
endif
@ -27,24 +30,21 @@ 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
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}/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"
@ -59,7 +59,7 @@ metaverse.elf: kernel libk rust metaverse.lds
all: postproc metaverse.elf
@echo -e "Build \e[1;32msucceeded\e[0m."
@echo -e "Build ID \e[1;31m$(shell "${SOURCE}/magicgen"|sha512sum|head -c 128|md5sum|head -c 8)\e[0m."
@echo -e "Build ID \e[1;31m${BUILD_ID}\e[0m."
postproc:
@echo -n -e "\e[36m"

View File

@ -7,12 +7,14 @@ CC = gcc
CCFLAGS = -m64 -mcmodel=large -I ../../include \
-fno-stack-protector -fno-exceptions \
-fno-builtin -nostdinc -nostdlib \
-DMEMM_ALLOCATOR_MAGIC="(u32)(0x${ALLOCATOR_MAGIC})"
-DMEMM_ALLOCATOR_MAGIC="(u32)(0x${ALLOCATOR_MAGIC})" \
-DBUILD_ID="${BUILD_ID}"
ifdef release
CCFLAGS := ${CCFLAGS} -O2
endif
C_SRCS = main.c tty.c font.c memm.c memm_${ARCH}.c raw.c time.c syscall_${ARCH}.c
C_SRCS = main.c tty.c font.c memm.c memm_${ARCH}.c raw.c time.c syscall_${ARCH}.c interrupt_${ARCH}.c \
interrupt_procs.c
C_OBJS = ${C_SRCS:.c=.c.o}
################################
@ -27,7 +29,8 @@ endif
ASMFLAGS := ${ASMFLAGS}
ASMFLAGS32 = -f elf32
S_SRCS = entry32.s entry.s memm_${ARCH}.s kernel.s syscall_${ARCH}.s
S_SRCS = entry32.s entry.s memm_${ARCH}.s kernel.s syscall_${ARCH}.s interrupt_${ARCH}.s \
interrupt_procs.s
S_OBJS = ${S_SRCS:.s=.s.o}
################################

View File

@ -105,7 +105,7 @@ gdt:
dq 0x0020f80000000000 ; 用户态代码段
dq 0x0000f20000000000 ; 用户态数据段
dq 0
dq 0x0000891070000000 ; TSS段低64位
dq 0x0000891070000068 ; TSS段低64位
dq 0 ; TSS段高64位
gdt_end:

View File

@ -0,0 +1,79 @@
%macro store_regs 0
push rax
push rcx
push rbx
push rdx
push rsi
push rdi
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
%endmacro
%macro retrieve_regs 0
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rdi
pop rsi
pop rdx
pop rbx
pop rcx
pop rax
%endmacro
%macro switch_section 0
sub rsp, 4
mov ax, ds
push ax
mov ax, es
push ax
mov ax, 0x10
mov ds, ax
mov es, ax
%endmacro
%macro retrieve_section 0
pop ax
mov es, ax
pop ax
mov ds, ax
add rsp, 4
%endmacro
%macro interrupt_entry_enter 0
push rbp
lea rbp, [rsp]
store_regs
switch_section
%endmacro
%macro interrupt_entry_leave 0
retrieve_section
retrieve_regs
leave
%endmacro
; 用于带有错误码的中断,创建一个没有错误码的上下文拷贝
%macro interrupt_stack_wrap_texture 0
extern memcpy
sub rsp, 21 * 8
mov rdi, rsp
lea rsi, [rsp + 21 * 8]
mov rdx, 16 * 8
call memcpy
lea rdi, [rsp + 16 * 8]
lea rsi, [rsp + 38 * 8]
mov rdx, 5 * 8
call memcpy
%endmacro

View File

@ -0,0 +1,190 @@
#include <kernel/arch/x86_64/interrupt_procs.h>
#include <kernel/arch/x86_64/memm.h>
#include <kernel/arch/x86_64/proc.h>
#include <kernel/kernel.h>
#include <kernel/tty.h>
#include <libk/string.h>
interrupt_req_gen(UNSUPPORTED)
{
tty **tty0_option = tty_get(0);
if (tty0_option == nullptr)
{
KERNEL_TODO();
}
tty *tty0 = *tty0_option;
tty_text_print(tty0, "Panic: Unsupported interrupt.", RED, BLACK);
KERNEL_TODO();
}
static void rip_not_cannonical(u64 rip, tty *tty0)
{
char num[17];
memset(num, 0, sizeof(num));
pointer_to_string(rip, num);
tty_text_print(tty0, "Panic", RED, BLACK);
tty_text_print(tty0, ": Unexpected non-cannonical %rip value ", WHITE, BLACK);
tty_text_print(tty0, num, ORANGE, BLACK);
tty_text_print(tty0, ".\n", WHITE, BLACK);
KERNEL_TODO();
}
interrupt_req_gen(DE)
{
tty **tty0_option = tty_get(0);
if (tty0_option == nullptr)
{
KERNEL_TODO();
}
tty *tty0 = *tty0_option;
if (!is_cannonical(rip))
{
rip_not_cannonical(rip, tty0);
}
if (!is_user_address(rip))
{
char nums[34];
memset(nums, 0, sizeof(nums));
pointer_to_string(rip, nums);
pointer_to_string(rsp, nums + 17);
tty_text_print(tty0, "Panic", RED, BLACK);
tty_text_print(tty0, ": Divided by zero occurs in kernel,\n\t", WHITE, BLACK);
tty_text_print(tty0, "with %rip=", WHITE, BLACK);
tty_text_print(tty0, "0x", ORANGE, BLACK);
tty_text_print(tty0, nums, ORANGE, BLACK);
tty_text_print(tty0, ", %rsp=", WHITE, BLACK);
tty_text_print(tty0, "0x", ORANGE, BLACK);
tty_text_print(tty0, nums + 17, ORANGE, BLACK);
tty_text_print(tty0, ".\n", WHITE, BLACK);
KERNEL_TODO();
}
else
{ // TODO 转储并结束进程
KERNEL_TODO();
}
}
interrupt_req_gen(BP)
{
tty **tty0_option = tty_get(0);
if (tty0_option == nullptr)
{
KERNEL_TODO();
}
tty *tty0 = *tty0_option;
if (!is_cannonical(rip))
{
rip_not_cannonical(rip, tty0);
}
proc_texture_registers_t *texture = (void *)errcode;
if (!is_user_address(rip))
{
char nums[34];
memset(nums, 0, sizeof(nums));
pointer_to_string(rip, nums);
pointer_to_string(rsp, nums + 17);
tty_text_print(tty0, "Debug", PURPLE, BLACK);
tty_text_print(tty0, ": Kernel hit a breakpoint,\n\t", WHITE, BLACK);
tty_text_print(tty0, "with %rip=", WHITE, BLACK);
tty_text_print(tty0, "0x", ORANGE, BLACK);
tty_text_print(tty0, nums, ORANGE, BLACK);
tty_text_print(tty0, ", %rsp=", WHITE, BLACK);
tty_text_print(tty0, "0x", ORANGE, BLACK);
tty_text_print(tty0, nums + 17, ORANGE, BLACK);
tty_text_print(tty0, ",\n\t", WHITE, BLACK);
tty_text_print(tty0, "on texture: \n", WHITE, BLACK);
pointer_to_string(texture->rax, nums);
tty_text_print(tty0, "rax\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\t", WHITE, BLACK);
pointer_to_string(texture->rcx, nums);
tty_text_print(tty0, "rcx\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\n", WHITE, BLACK);
pointer_to_string(texture->rbx, nums);
tty_text_print(tty0, "rbx\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\t", WHITE, BLACK);
pointer_to_string(texture->rdx, nums);
tty_text_print(tty0, "rdx\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\n", WHITE, BLACK);
pointer_to_string(texture->rsi, nums);
tty_text_print(tty0, "rsi\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\t", WHITE, BLACK);
pointer_to_string(texture->rdi, nums);
tty_text_print(tty0, "rdi\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\n", WHITE, BLACK);
pointer_to_string(texture->rbp, nums);
tty_text_print(tty0, "rbp\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\t", WHITE, BLACK);
pointer_to_string(texture->rsp, nums);
tty_text_print(tty0, "rsp\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\n", WHITE, BLACK);
pointer_to_string(texture->rip, nums);
tty_text_print(tty0, "rip\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\t", WHITE, BLACK);
pointer_to_string(texture->rflags, nums);
tty_text_print(tty0, "rflags\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\n", WHITE, BLACK);
pointer_to_string(texture->r8, nums);
tty_text_print(tty0, "r8\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\t", WHITE, BLACK);
pointer_to_string(texture->r9, nums);
tty_text_print(tty0, "r9\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\n", WHITE, BLACK);
pointer_to_string(texture->r10, nums);
tty_text_print(tty0, "r10\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\t", WHITE, BLACK);
pointer_to_string(texture->r11, nums);
tty_text_print(tty0, "r11\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\n", WHITE, BLACK);
pointer_to_string(texture->r12, nums);
tty_text_print(tty0, "r12\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\t", WHITE, BLACK);
pointer_to_string(texture->r13, nums);
tty_text_print(tty0, "r13\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\n", WHITE, BLACK);
pointer_to_string(texture->r14, nums);
tty_text_print(tty0, "r14\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\t", WHITE, BLACK);
pointer_to_string(texture->r15, nums);
tty_text_print(tty0, "r15\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\n", WHITE, BLACK);
pointer_to_string(texture->cs, nums);
tty_text_print(tty0, "cs\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\t", WHITE, BLACK);
pointer_to_string(texture->ss, nums);
tty_text_print(tty0, "ss\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\n", WHITE, BLACK);
pointer_to_string(texture->ds, nums);
tty_text_print(tty0, "ds\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\t", WHITE, BLACK);
pointer_to_string(texture->es, nums);
tty_text_print(tty0, "es\t", WHITE, BLACK);
tty_text_print(tty0, nums, BLUE, BLACK);
tty_text_print(tty0, "\n", WHITE, BLACK);
KERNEL_TODO();
}
else
{ // TODO 将当前进程的状态设置为暂停并通知当前进程的调试程序
KERNEL_TODO();
}
}

View File

@ -0,0 +1,97 @@
%include "arch/x86_64/interrupt.in"
; 栈中的寄存器上下文
; +------------
; | ss
; +------------<-- rsp+168(+160)
; | rsp
; +------------<-- rsp+160(+152)
; | rflags
; +------------<-- rsp+152(+144)
; | cs
; +------------<-- rsp+144(+136)
; | rip
; +------------<-- rsp+136(+128)
; | (err code)
; +------------<-- rsp+128
; | rbp
; +------------<-- rsp+120
; | rax
; +------------<-- rsp+112
; | rcx
; +------------<-- rsp+104
; | rbx
; +------------<-- rsp+96
; | rdx
; +------------<-- rsp+88
; | rsi
; +------------<-- rsp+80
; | rdi
; +------------<-- rsp+72
; | r8
; +------------<-- rsp+64
; | r9
; +------------<-- rsp+56
; | r10
; +------------<-- rsp+48
; | r11
; +------------<-- rsp+40
; | r12
; +------------<-- rsp+32
; | r13
; +------------<-- rsp+24
; | r14
; +------------<-- rsp+16
; | r15
; +------------<-- rsp+8
; | reserved
; +------------<-- rsp+4
; | ds
; +------------<-- rsp+2
; | es
; +------------<-- rsp+0
section .text
global interrupt_entry_UNSUPPORTED
extern interrupt_req_UNSUPPORTED
interrupt_entry_UNSUPPORTED:
interrupt_entry_enter
mov rdi, [rsp + 128]
mov rsi, [rsp + 152]
call interrupt_req_UNSUPPORTED
interrupt_entry_leave
iret
global interrupt_entry_DE
extern interrupt_req_DE
interrupt_entry_DE:
interrupt_entry_enter
mov rdi, [rsp + 128]
mov rsi, [rsp + 152]
call interrupt_req_DE
interrupt_entry_leave
iret
global interrupt_entry_DE
interrupt_entry_NMI:
; TODO 暂时不需要为这个中断实现任何功能
iret
global interrupt_entry_BP
extern interrupt_req_BP
interrupt_entry_BP:
interrupt_entry_enter
mov rdi, [rsp + 128]
mov rsi, [rsp + 152]
mov dword [rsp + 4], 0
mov rdx, rsp
call interrupt_req_BP
interrupt_entry_leave
iret

View File

@ -0,0 +1,25 @@
#include <kernel/interrupt.h>
#include <utils.h>
#include <kernel/arch/x86_64/interrupt_procs.h>
void interrupt_init()
{
gate_descriptor_t gate;
trap_gate_generate(gate, interrupt_entry_sym(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));
interrupt_register_gate(gate, 1);
trap_gate_generate(gate, interrupt_entry_sym(NMI));
interrupt_register_gate(gate, 2);
trap_gate_generate(gate, interrupt_entry_sym(BP));
interrupt_register_gate(gate, 3);
interrupt_open();
}

View File

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

View File

@ -19,13 +19,3 @@ prepare_stack:
mov rax, [rax]
mov [rsp], rax
ret
global interrupt_open
interrupt_open:
sti
ret
global interrupt_close
interrupt_close:
cli
ret

View File

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

View File

@ -43,6 +43,10 @@ void kmain(void *mb2_bootinfo)
get_frame_buffer_with_bootinfo(&fb, &bootinfo);
tty *tty0 = tty_new(tty_type_raw_framebuffer, tty_mode_text);
tty_set_framebuffer(tty0, &fb);
tty_enable(tty0);
// 初始化中断管理
interrupt_init();
// 初始化系统调用
syscall_init();

View File

@ -8,7 +8,6 @@ use super::{
#[no_mangle]
extern "C" fn kmain_rust() -> ! {
let tty = Tty::from_id(0).unwrap();
tty.enable();
let mut logger = KernelLogger::new();
logger.info(message!(
Msg("Hello, "),

View File

@ -72,7 +72,7 @@ void raw_allocator_free(raw_allocator_t *allocator, void *mem)
{
raw_allocator_cell *cell = allocator->cells;
while ((void *)cell < raw_allocator_end(allocator))
{
{ // TODO 内存错误
if (mem == cell->content)
{
cell->length = 0;
@ -83,7 +83,7 @@ void raw_allocator_free(raw_allocator_t *allocator, void *mem)
allocator->rest_memory += cell->capacity + sizeof(raw_allocator_cell);
allocator->free_count++;
if ( // 可用内存不超过当前allocator的 5% 或调用free次数很多时
allocator->size / allocator->rest_memory > 20 &&
allocator->size / allocator->rest_memory > 20 ||
allocator->free_count > RAW_ALLOCATOR_FREE_MAX)
{
raw_allocator_cellmerge(allocator);

View File

@ -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;
}
@ -79,7 +37,6 @@ allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid
allocator_t *allocator = start;
allocator->magic = MEMM_ALLOCATOR_MAGIC;
allocator->full = false;
allocator->pid = 0;
allocator->size = length;
allocator->type = type;
switch (type)
@ -102,157 +59,31 @@ 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))
{
mem = mem - allocator->userspace + (void *)allocator;
}
allocator->free(allocator->allocator_instance, mem);
if (allocator->full)
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
}
}

View File

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

View File

@ -11,7 +11,7 @@ ifdef release
CCFLAGS := ${CCFLAGS} -O2
endif
C_SRCS = bootinfo.c lst.c
C_SRCS = bootinfo.c lst.c utils.c
C_OBJS = ${C_SRCS:.c=.c.o}
################################

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

@ -0,0 +1,11 @@
#include <utils.h>
void pointer_to_string(u64 addr, char *dest)
{
for (u8 i = 0; i < 16; i++)
{
char c = addr & 0xf;
dest[15 - i] = (c < 10) ? c + '0' : c - 10 + 'a';
addr >>= 4;
}
}