forked from metaverse/kernel-dev
Compare commits
17 Commits
5dc9de8195
...
46b80996f7
Author | SHA1 | Date |
---|---|---|
pointer-to-bios | 46b80996f7 | |
pointer-to-bios | 77b8b4cd7c | |
pointer-to-bios | ad8cb92e78 | |
pointer-to-bios | 327c10963c | |
pointer-to-bios | 8f82c88e30 | |
pointer-to-bios | 22781004d0 | |
pointer-to-bios | 00d655c468 | |
pointer-to-bios | b0b790fab8 | |
pointer-to-bios | 8d4938c7ba | |
pointer-to-bios | 341ca618de | |
pointer-to-bios | 37ee2ca85d | |
pointer-to-bios | bec4634857 | |
pointer-to-bios | 88acd1900f | |
pointer-to-bios | 0b8d6db7b7 | |
pointer-to-bios | 933eaf3305 | |
pointer-to-bios | 38d65b4d70 | |
pointer-to-bios | 9b9fcc87cf |
|
@ -1,3 +1,3 @@
|
|||
[submodule "rustlib"]
|
||||
path = rustlib
|
||||
url = http://git.suthby.org:2024/metaverse/rustenv
|
||||
url = https://github.com/metaverse-kernel/rustenv.git
|
||||
|
|
|
@ -3,6 +3,9 @@ name = "metaverse"
|
|||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib"]
|
||||
|
||||
# 此Cargo.toml仅用于rust-analyzer识别rust部分的代码
|
||||
# 不应使用cargo编译
|
||||
|
||||
|
|
36
Makefile
36
Makefile
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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页大小
|
||||
|
|
|
@ -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
|
|
@ -24,6 +24,8 @@ extern void *system_calls_table[256];
|
|||
* r14 - 参数7
|
||||
* r15 - 参数8
|
||||
*
|
||||
* 返回值 - rax
|
||||
*
|
||||
* 系统调用时,使用内核主堆栈。
|
||||
*/
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef INTERRUPT_PROCS
|
||||
#define INTERRUPT_PROCS 1
|
||||
|
||||
#ifdef __x86_64__
|
||||
#include <kernel/arch/x86_64/interrupt_procs.h>
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -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
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
[toolchain]
|
||||
channel = "stable"
|
2
rustlib
2
rustlib
|
@ -1 +1 @@
|
|||
Subproject commit 087c4795bbc23cd0baee060bda8c1159a971a542
|
||||
Subproject commit bb4a5d1b55c36070d629400bddd6d267d2f0714a
|
|
@ -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'])
|
||||
|
|
16
src/Makefile
16
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
|
||||
|
@ -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"
|
||||
|
|
|
@ -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}
|
||||
|
||||
################################
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
section .text
|
||||
|
||||
global interrupt_open
|
||||
interrupt_open:
|
||||
sti
|
||||
ret
|
||||
|
||||
global interrupt_close
|
||||
interrupt_close:
|
||||
cli
|
||||
ret
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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, "),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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}
|
||||
|
||||
################################
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue