Merge pull request '重写rust核心库,构建中断处理框架' (#6) from pointer-to-bios/metaverse-dev:main into main
Reviewed-on: metaverse/kernel-dev#6
This commit is contained in:
commit
87f2767499
|
@ -0,0 +1,2 @@
|
||||||
|
[build]
|
||||||
|
target = ["x86_64-unknown-none"]
|
|
@ -1,5 +1,7 @@
|
||||||
|
.vscode
|
||||||
/test/metaverse.img
|
/test/metaverse.img
|
||||||
*.o
|
*.o
|
||||||
|
*.tfo
|
||||||
*.map
|
*.map
|
||||||
*.elf
|
*.elf
|
||||||
metaverse_kernel
|
metaverse_kernel
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
[submodule "rustlib"]
|
|
||||||
path = rustlib
|
|
||||||
url = http://git.suthby.org:2024/metaverse/rustenv
|
|
|
@ -1,16 +0,0 @@
|
||||||
{
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"name": "Linux",
|
|
||||||
"includePath": [
|
|
||||||
"${workspaceFolder}/include"
|
|
||||||
],
|
|
||||||
"defines": [],
|
|
||||||
"compilerPath": "/usr/bin/gcc",
|
|
||||||
"cStandard": "c17",
|
|
||||||
"intelliSenseMode": "linux-gcc-x64",
|
|
||||||
"configurationProvider": "ms-vscode.makefile-tools"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"version": 4
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"C_Cpp.errorSquiggles": "disabled",
|
|
||||||
"files.associations": {
|
|
||||||
"*.s": "nasm",
|
|
||||||
"LICENCE": "plaintext",
|
|
||||||
"*.h": "c"
|
|
||||||
},
|
|
||||||
"rust-analyzer.imports.preferNoStd" : true,
|
|
||||||
}
|
|
|
@ -2,10 +2,10 @@
|
||||||
name = "metaverse"
|
name = "metaverse"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
crate-type = ["staticlib"]
|
crate-type = ["staticlib"]
|
||||||
|
test = false
|
||||||
|
|
||||||
# 此Cargo.toml仅用于rust-analyzer识别rust部分的代码
|
# 此Cargo.toml仅用于rust-analyzer识别rust部分的代码
|
||||||
# 不应使用cargo编译
|
# 不应使用cargo编译
|
||||||
|
|
||||||
[target.'cfg(target_arch = "x86_64")']
|
|
||||||
target = "x86_64-unknown-none"
|
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
======== 04-21 16:50 ========
|
||||||
|
Hit null pointer at 0x100370a
|
||||||
|
Stack trace:
|
||||||
|
1 0x0000000001007b90 -> interrupt_req_DE
|
||||||
|
2 0x00000000010072b0 -> metaverse::kernel::tty::tty::MessageBuilder::message_mut
|
||||||
|
3 0x0000000001007e60 -> <metaverse::libk::alloc::string::String as core::iter::traits::collect::FromIterator::<char>>::from_iter
|
||||||
|
4 0x0000000001005eb0 -> <alloc::string::String as core::iter::traits::collect::FromIterator<char>>::from_iter
|
||||||
|
5 0x0000000001005d80 -> <alloc::string::String as core::iter::traits::collect::Extend<char>>::extend
|
||||||
|
6 0x0000000001004840 -> alloc::vec::Vec::reserve
|
||||||
|
7 0x0000000001005900 -> alloc::raw_vec::RawVec::reserve::{do_reserve_and_handle}
|
||||||
|
8 0x00000000010055c0 -> alloc::raw_vec::RawVec::grow_amortized
|
||||||
|
9 0x00000000010051e0 -> alloc::raw_vec::finish_grow
|
||||||
|
10 0x0000000001005a90 -> <alloc::alloc::Global as core::alloc::Allocator>::allocate
|
||||||
|
11 0x0000000001004900 -> alloc::alloc::Global::alloc_impl
|
||||||
|
12 0x00000000010048a0 -> alloc::alloc::alloc
|
||||||
|
13 0x00000000010036e0 -> core::ptr::read_volatile::precondition_check
|
||||||
|
使用了core crate中的String,导致最终调用了一个含有未正确链接的函数。
|
||||||
|
|
||||||
|
======== 04-23 13:55 ========
|
||||||
|
Hit null pointer at 0x100351a.
|
||||||
|
Stack trace:
|
||||||
|
0x00000000010054d0 -> metaverse::kernel::tty::tty::MessageBuilder::message_mut
|
||||||
|
0x0000000001006170 -> <str as metaverse::libk::alloc::string::ToString>::to_string
|
||||||
|
0x0000000001006080 -> <metaverse::libk::alloc::string::String as core::iter::traits::collect::FromIterator<char>>::from_iter
|
||||||
|
0x0000000001007450 -> <metaverse::libk::alloc::vec::Vec as core::iter::traits::collect::FromIterator>::from_iter
|
||||||
|
0x0000000001006a10 -> metaverse::libk::alloc::vec::Vec::push
|
||||||
|
0x0000000001003f60 -> alloc::alloc::alloc
|
||||||
|
0x00000000010034f0 -> core::ptr::read_volatile::precondition_check
|
||||||
|
使用了core crate的alloc函数,其中含有未正确链接的函数。
|
||||||
|
|
||||||
|
======== 04-26 02:56 ========
|
||||||
|
Hit null pointer in metaverse::libk::alloc::string::String::clone()
|
||||||
|
Stack trace:
|
||||||
|
0x0000000001005520 -> metaverse::kernel::tty::tty::format_message
|
||||||
|
0x00000000010052f0 -> metaverse::kernel::tty::tty::MessageBuilder::message_mut
|
||||||
|
0x00000000010073f0 -> <metaverse::libk::alloc::string::String as metaverse::libk::alloc::string::ToString>::to_string
|
||||||
|
0x0000000001009a90 -> <metaverse::libk::alloc::string::String as core::clone::Clone>::clone
|
||||||
|
使用了Clone的derive宏,含有未正确链接的函数。
|
||||||
|
|
||||||
|
======== 04-26 15:55 ========
|
||||||
|
Hit null pointer at 0x1003672.
|
||||||
|
Stack trace:
|
||||||
|
0x0000000001007600 -> <u64 as metaverse::libk::alloc::string::ToString>::to_string
|
||||||
|
0x0000000001007030 -> metaverse::libk::alloc::string::String::insert
|
||||||
|
0x0000000001008330 -> metaverse::libk::alloc::vec::Vec::insert
|
||||||
|
0x0000000001007950 -> metaverse::libk::alloc::vec::Vec::extend_capacity
|
||||||
|
0x0000000001003630 -> core::intrinsics::copy::precondition_check
|
||||||
|
将*mut u8转换为*mut T时调用了此函数,导致调用了一个未正确链接的函数。
|
||||||
|
|
||||||
|
======== 04-27 16:06 ========
|
||||||
|
Trapped into a infinite loop.
|
||||||
|
Stack trace:
|
||||||
|
0x0000000001006c30 -> interrupt_req_DE
|
||||||
|
0x0000000001005420 -> metaverse::kernel::tty::tty::MessageBuilder::append
|
||||||
|
0x0000000001008410 -> metaverse::libk::alloc::vec::Vec::append
|
|
@ -12,9 +12,22 @@
|
||||||
|
|
||||||
若你的代码通过审核,将会把你的PR合并到主分支中。
|
若你的代码通过审核,将会把你的PR合并到主分支中。
|
||||||
|
|
||||||
## 需要注意的还未解决的问题
|
## 开发引导
|
||||||
|
|
||||||
* rust中所有有关字符串格式化的宏中,出现超过一个不止是`{}`的格式化占位符时内核必然崩溃。
|
## vscode
|
||||||
* rust中所有有关字符串格式化的宏中,出现需要调用自定义的`Debug trait`的类型时内核必然崩溃,推荐定义`ToString trait`并调用`.to_string()`后传入宏参数。
|
|
||||||
* 鉴于以上两条原因,不建议在复杂的字符串格式化任务中使用`format!()`宏。推荐通过使用`::kernel::tty::tty::MessageBuilder`构造`kernel::tty::tty::Message`对象,或使用
|
vscode下的`rust-analyzer`插件会在`src/lib.rs`中误报`can't find crate for test`,实际上在`Cargo.toml`中已经增加了`test = false`选项。
|
||||||
`message`宏,并调用此对象的`.to_string()`方法实现格式化字符串。
|
|
||||||
|
解决方法是在`.vscode/settings.json`中增加两项:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"rust-analyzer.cargo.allTargets": false,
|
||||||
|
"rust-analyzer.cargo.extraArgs": [
|
||||||
|
"--target",
|
||||||
|
"开发的目标平台的unknown-none类型目标(如x86_64-unknown-none)"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## 需要注意的问题
|
||||||
|
|
||||||
|
* 在任何情况下不要使用Rust的panic。
|
||||||
|
|
|
@ -77,11 +77,13 @@ typedef void (*interrupt_request)(u64 rip, u64 rsp, u64 errcode);
|
||||||
#define DE
|
#define DE
|
||||||
#define NMI
|
#define NMI
|
||||||
#define BP
|
#define BP
|
||||||
|
#define OF
|
||||||
|
|
||||||
interrupt_entry_gen(UNSUPPORTED);
|
interrupt_entry_gen(UNSUPPORTED);
|
||||||
|
|
||||||
interrupt_entry_gen(DE);
|
interrupt_entry_gen(DE); // irq0
|
||||||
interrupt_entry_gen(NMI);
|
interrupt_entry_gen(NMI); // irq2
|
||||||
interrupt_entry_gen(BP);
|
interrupt_entry_gen(BP); // irq3
|
||||||
|
interrupt_entry_gen(OF); // ira4
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -156,6 +156,7 @@ void tty_disable(tty *ttyx);
|
||||||
|
|
||||||
typedef struct __tty_font_t
|
typedef struct __tty_font_t
|
||||||
{
|
{
|
||||||
|
bool initialized;
|
||||||
u16 char_width, char_height;
|
u16 char_width, char_height;
|
||||||
u64 **font;
|
u64 **font;
|
||||||
} tty_font_t;
|
} tty_font_t;
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "stable"
|
channel = "nightly"
|
||||||
|
|
1
rustlib
1
rustlib
|
@ -1 +0,0 @@
|
||||||
Subproject commit 6a2ca2afcd651e46f1c19f8d8a3f685fd982d824
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
from io import TextIOWrapper
|
||||||
|
import sys
|
||||||
|
import struct
|
||||||
|
|
||||||
|
|
||||||
|
def main(infile: TextIOWrapper, outfile: TextIOWrapper):
|
||||||
|
size = infile.readline().strip().split(",")
|
||||||
|
size = (int(size[0].strip()), int(size[1].strip()))
|
||||||
|
outfile.write(struct.pack('q', size[0]))
|
||||||
|
outfile.write(struct.pack('q', size[1]))
|
||||||
|
for _ in range(62):
|
||||||
|
outfile.write(struct.pack('q', int(0)))
|
||||||
|
in_char = False
|
||||||
|
char_buffer = []
|
||||||
|
char_count = 0
|
||||||
|
for line in infile:
|
||||||
|
line = line.split("//")[0].strip()
|
||||||
|
if len(line) == 0:
|
||||||
|
continue
|
||||||
|
if line.startswith("{"):
|
||||||
|
char_buffer = []
|
||||||
|
line = line[1:]
|
||||||
|
in_char = True
|
||||||
|
if line.endswith("},"):
|
||||||
|
i = 0
|
||||||
|
for d in char_buffer:
|
||||||
|
outfile.write(struct.pack('q', d))
|
||||||
|
i += 1
|
||||||
|
while i < 64:
|
||||||
|
outfile.write(struct.pack('q', int(0)))
|
||||||
|
i += 1
|
||||||
|
char_count += 1
|
||||||
|
in_char = False
|
||||||
|
continue
|
||||||
|
if len(line) == 0:
|
||||||
|
continue
|
||||||
|
if in_char:
|
||||||
|
data = line.split(",")[0].strip()
|
||||||
|
data = int(data, 2)
|
||||||
|
char_buffer.append(data)
|
||||||
|
while char_count < 256:
|
||||||
|
for _ in range(64):
|
||||||
|
outfile.write(struct.pack('q', int(0)))
|
||||||
|
char_count += 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) < 3:
|
||||||
|
print("tfgen: Input file and Output file needed.")
|
||||||
|
exit(1)
|
||||||
|
infile_name = sys.argv[1]
|
||||||
|
outfile_name = sys.argv[2]
|
||||||
|
with open(infile_name) as infile:
|
||||||
|
with open(outfile_name, "wb") as outfile:
|
||||||
|
main(infile, outfile)
|
43
src/Makefile
43
src/Makefile
|
@ -12,11 +12,15 @@ ifdef release
|
||||||
release = 1
|
release = 1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifndef ttyfont
|
||||||
|
ttyfont = metamono
|
||||||
|
endif
|
||||||
|
|
||||||
ALLOCATOR_MAGIC = $(shell "${SOURCE}/magicgen" | sha512sum | head -c 128 | md5sum | head -c 8)
|
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)
|
BUILD_ID = $(shell "${SOURCE}/magicgen" | sha512sum | head -c 128 | md5sum | head -c 8)
|
||||||
|
|
||||||
SUBOBJS = kernel/kernel.o libk/libk.o rust.o
|
SUBOBJS = kernel/kernel.o libk/libk.o rust.o font_file.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}" BUILD_ID="${BUILD_ID}"
|
ALLOCATOR_MAGIC="${ALLOCATOR_MAGIC}" BUILD_ID="${BUILD_ID}"
|
||||||
|
@ -27,16 +31,24 @@ endif
|
||||||
################################
|
################################
|
||||||
# rust语言环境变量
|
# rust语言环境变量
|
||||||
|
|
||||||
|
TARGET_TRIPLE =
|
||||||
|
|
||||||
|
ifeq (${ARCH},x86_64)
|
||||||
|
TARGET_TRIPLE := x86_64-unknown-none
|
||||||
|
endif
|
||||||
|
|
||||||
|
RUSTLIB_PATH = ../target/sysroot/lib/rustlib/${TARGET_TRIPLE}/lib
|
||||||
|
RUST_LIBS = $(shell ls -d ${RUSTLIB_PATH}/lib*.rlib)
|
||||||
|
|
||||||
RSCFLAGS = --emit obj --crate-type staticlib --verbose \
|
RSCFLAGS = --emit obj --crate-type staticlib --verbose \
|
||||||
--crate-name=metaverse \
|
--crate-name=metaverse \
|
||||||
--edition 2021 \
|
--edition 2021 \
|
||||||
-L crate="${PWD}/../rustlib/src/" \
|
|
||||||
-C code-model=large \
|
-C code-model=large \
|
||||||
-C relocation-model=static \
|
-C relocation-model=static \
|
||||||
-C embed-bitcode=no
|
-C embed-bitcode=no \
|
||||||
|
-C panic=abort
|
||||||
|
|
||||||
ifeq (${ARCH},x86_64)
|
ifeq (${ARCH},x86_64)
|
||||||
RSCFLAGS := ${RSCFLAGS} --target x86_64-unknown-none
|
|
||||||
RSCFLAGS := ${RSCFLAGS} -C target-feature=-sse
|
RSCFLAGS := ${RSCFLAGS} -C target-feature=-sse
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -44,18 +56,14 @@ ifdef release
|
||||||
RSCFLAGS := ${RSCFLAGS} -O
|
RSCFLAGS := ${RSCFLAGS} -O
|
||||||
endif
|
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"
|
|
||||||
|
|
||||||
################################
|
################################
|
||||||
|
|
||||||
metaverse.elf: kernel libk rust metaverse.lds
|
metaverse.elf: kernel libk rust metaverse.lds font_file.o
|
||||||
@echo -e "\e[1;33mld\e[0m \e[1;32m$@\e[0m \e[34m<--\e[0m \e[32m${SUBOBJS}\e[0m"
|
@echo -e "\e[1;33mld\e[0m \e[1;32m$@\e[0m \e[34m<--\e[0m \e[32m${SUBOBJS}\e[0m"
|
||||||
@ld -T metaverse.lds -Map=metaverse.map -unresolved-symbols=ignore-all -o $@ ${SUBOBJS} ${RUST_LIBS} \
|
@ld -T metaverse.lds -Map=metaverse.map -unresolved-symbols=ignore-all -o $@ ${SUBOBJS} ${RUST_LIBS} \
|
||||||
2>&1 | "${SOURCE}/colorize" "warning:=yellow" "error:=red" "ld=lyellow"
|
2>&1 | "${SOURCE}/colorize" "warning:=lpink" "error:=red" "ld=lyellow"
|
||||||
|
|
||||||
.PHONY: kernel libk all clear postproc rust
|
.PHONY: kernel libk all clear postproc rust rustlib
|
||||||
|
|
||||||
all: postproc metaverse.elf
|
all: postproc metaverse.elf
|
||||||
@echo -e "Build \e[1;32msucceeded\e[0m."
|
@echo -e "Build \e[1;32msucceeded\e[0m."
|
||||||
|
@ -88,11 +96,18 @@ libk:
|
||||||
echo -e "\e[33m-------------------------\e[0m"; \
|
echo -e "\e[33m-------------------------\e[0m"; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rust: postproc
|
../target:
|
||||||
|
@-cargo xbuild --target ${TARGET_TRIPLE} --release
|
||||||
|
|
||||||
|
rust: postproc ../target
|
||||||
@echo -e "\e[1m\e[33mrustc\e[0m \e[34m-->\e[0m \e[1m\e[32m$@.o\e[0m"
|
@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
|
@rustc ${RSCFLAGS} lib.rs -o rust.o
|
||||||
|
|
||||||
|
font_file.o: ttyfonts/${ttyfont}.tfn
|
||||||
|
@"${SOURCE}/tfgen" $< font_file.tfo
|
||||||
|
@ld -r -b binary -o $@ font_file.tfo
|
||||||
|
|
||||||
clear:
|
clear:
|
||||||
@make -C kernel clear --no-print-directory ${DEFINES}
|
@make -C kernel clear --no-print-directory ${DEFINES}
|
||||||
@make -C libk clear --no-print-directory ${DEFINES}
|
@make -C libk clear --no-print-directory ${DEFINES}
|
||||||
@-rm metaverse.elf metaverse.map rust.o
|
@-rm metaverse.elf metaverse.map rust.o font_file.{o,tfo}
|
||||||
|
|
|
@ -13,8 +13,7 @@ ifdef release
|
||||||
CCFLAGS := ${CCFLAGS} -O2
|
CCFLAGS := ${CCFLAGS} -O2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
C_SRCS = main.c tty.c font.c memm.c memm_${ARCH}.c raw.c time.c syscall_${ARCH}.c interrupt_${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}
|
C_OBJS = ${C_SRCS:.c=.c.o}
|
||||||
|
|
||||||
################################
|
################################
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
pub mod x86_64;
|
|
@ -11,7 +11,8 @@ init64:
|
||||||
mov rsp, rax
|
mov rsp, rax
|
||||||
mov rdi, rbx
|
mov rdi, rbx
|
||||||
|
|
||||||
lidt [0x104010]
|
; 加载idt
|
||||||
|
lidt [0x104010] ; idt_ptr
|
||||||
|
|
||||||
; 加载系统调用相关寄存器
|
; 加载系统调用相关寄存器
|
||||||
; IA32_STAR = 0x0018_0008_0000_0000
|
; IA32_STAR = 0x0018_0008_0000_0000
|
||||||
|
|
|
@ -21,17 +21,18 @@ init32:
|
||||||
mov dword [edi], 0
|
mov dword [edi], 0
|
||||||
|
|
||||||
; 设置PD0中的PDE
|
; 设置PD0中的PDE
|
||||||
mov ecx, 64
|
; 以2MB页映射前64MB
|
||||||
|
mov ecx, 32
|
||||||
mov eax, 0
|
mov eax, 0
|
||||||
mov edi, 0x103000 ; PD0
|
mov edi, 0x103000 ; PD0
|
||||||
init32_loop0:
|
init32_loop0:
|
||||||
mov edx, eax
|
mov edx, eax
|
||||||
add edx, 0x183
|
add edx, 0x183
|
||||||
mov dword [edi], edx
|
mov dword [edi], edx
|
||||||
add eax, 0x200000 ; 2MB
|
|
||||||
add edi, 4
|
add edi, 4
|
||||||
mov dword [edi], 0
|
mov dword [edi], 0
|
||||||
add edi, 4
|
add edi, 4
|
||||||
|
add eax, 0x200000 ; 2MB
|
||||||
loop init32_loop0
|
loop init32_loop0
|
||||||
|
|
||||||
; 加载GDTR、段寄存器和TR寄存器
|
; 加载GDTR、段寄存器和TR寄存器
|
||||||
|
|
|
@ -51,7 +51,10 @@
|
||||||
add rsp, 4
|
add rsp, 4
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
|
; 此处的cli在进入rust的中断处理函数后才会对应sti
|
||||||
|
; 因为在保存栈帧前中断不可以被打断
|
||||||
%macro interrupt_entry_enter 0
|
%macro interrupt_entry_enter 0
|
||||||
|
cli
|
||||||
push rbp
|
push rbp
|
||||||
lea rbp, [rsp]
|
lea rbp, [rsp]
|
||||||
store_regs
|
store_regs
|
||||||
|
@ -62,6 +65,7 @@
|
||||||
retrieve_section
|
retrieve_section
|
||||||
retrieve_regs
|
retrieve_regs
|
||||||
leave
|
leave
|
||||||
|
sti
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
; 用于带有错误码的中断,创建一个没有错误码的上下文拷贝
|
; 用于带有错误码的中断,创建一个没有错误码的上下文拷贝
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
use crate::{kernel::tty::tty::Tty, message};
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
pub fn interrupt_open();
|
||||||
|
pub fn interrupt_close();
|
||||||
|
// 以下两个函数签名的返回值用于使编译器保留rax寄存器
|
||||||
|
pub fn interrupt_rust_enter() -> usize;
|
||||||
|
pub fn interrupt_rust_leave() -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn interrupt_req_UNSUPPORTED(rip: u64, rsp: u64, errcode: u64) -> ! {
|
||||||
|
interrupt_rust_enter();
|
||||||
|
let tty = Tty::from_id(0).unwrap();
|
||||||
|
tty.enable();
|
||||||
|
tty.print(message!(
|
||||||
|
"{Panic}: Kernel hit an {Unsupported} interrupt on rip=0x{} and rsp=0x{}.\n",
|
||||||
|
FmtMeta::Color(Color::RED),
|
||||||
|
FmtMeta::Color(Color::YELLOW),
|
||||||
|
FmtMeta::Pointer(rip as usize),
|
||||||
|
FmtMeta::Pointer(rsp as usize)
|
||||||
|
));
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn interrupt_req_DE(rip: u64, rsp: u64, errcode: u64) {
|
||||||
|
interrupt_rust_enter();
|
||||||
|
let tty = Tty::from_id(0).unwrap();
|
||||||
|
tty.enable();
|
||||||
|
tty.print(message!(
|
||||||
|
"{Warning}: Kernel hit {Divid Error} on rip=0x{} and rsp=0x{}.\n",
|
||||||
|
FmtMeta::Color(Color::PURPLE),
|
||||||
|
FmtMeta::Color(Color::YELLOW),
|
||||||
|
FmtMeta::Pointer(rip as usize),
|
||||||
|
FmtMeta::Pointer(rsp as usize)
|
||||||
|
));
|
||||||
|
interrupt_rust_leave();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn interrupt_req_NMI(rip: u64, rsp: u64, errcode: u64) {}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn interrupt_req_BP(rip: u64, rsp: u64, errcode: u64) {}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
unsafe extern "C" fn interrupt_req_OF(rip: u64, rsp: u64, errcode: u64) {}
|
|
@ -1,190 +0,0 @@
|
||||||
#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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -63,7 +63,7 @@ interrupt_entry_UNSUPPORTED:
|
||||||
call interrupt_req_UNSUPPORTED
|
call interrupt_req_UNSUPPORTED
|
||||||
|
|
||||||
interrupt_entry_leave
|
interrupt_entry_leave
|
||||||
iret
|
iretq
|
||||||
|
|
||||||
global interrupt_entry_DE
|
global interrupt_entry_DE
|
||||||
extern interrupt_req_DE
|
extern interrupt_req_DE
|
||||||
|
@ -75,12 +75,12 @@ interrupt_entry_DE:
|
||||||
call interrupt_req_DE
|
call interrupt_req_DE
|
||||||
|
|
||||||
interrupt_entry_leave
|
interrupt_entry_leave
|
||||||
iret
|
iretq
|
||||||
|
|
||||||
global interrupt_entry_DE
|
global interrupt_entry_NMI
|
||||||
interrupt_entry_NMI:
|
interrupt_entry_NMI:
|
||||||
; TODO 暂时不需要为这个中断实现任何功能
|
; TODO 暂时不需要为这个中断实现任何功能
|
||||||
iret
|
iretq
|
||||||
|
|
||||||
global interrupt_entry_BP
|
global interrupt_entry_BP
|
||||||
extern interrupt_req_BP
|
extern interrupt_req_BP
|
||||||
|
@ -94,4 +94,16 @@ interrupt_entry_BP:
|
||||||
call interrupt_req_BP
|
call interrupt_req_BP
|
||||||
|
|
||||||
interrupt_entry_leave
|
interrupt_entry_leave
|
||||||
iret
|
iretq
|
||||||
|
|
||||||
|
global interrupt_entry_OF
|
||||||
|
extern interrupt_req_OF
|
||||||
|
interrupt_entry_OF:
|
||||||
|
interrupt_entry_enter
|
||||||
|
|
||||||
|
mov rdi, [rsp + 128]
|
||||||
|
mov rsi, [rsp + 152]
|
||||||
|
call interrupt_req_OF
|
||||||
|
|
||||||
|
interrupt_entry_leave
|
||||||
|
iretq
|
||||||
|
|
|
@ -20,6 +20,8 @@ void interrupt_init()
|
||||||
interrupt_register_gate(gate, 2);
|
interrupt_register_gate(gate, 2);
|
||||||
trap_gate_generate(gate, interrupt_entry_sym(BP));
|
trap_gate_generate(gate, interrupt_entry_sym(BP));
|
||||||
interrupt_register_gate(gate, 3);
|
interrupt_register_gate(gate, 3);
|
||||||
|
trap_gate_generate(gate, interrupt_entry_sym(OF));
|
||||||
|
interrupt_register_gate(gate, 4);
|
||||||
|
|
||||||
interrupt_open();
|
interrupt_open();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,3 +9,30 @@ interrupt_open:
|
||||||
interrupt_close:
|
interrupt_close:
|
||||||
cli
|
cli
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
global interrupt_rust_enter
|
||||||
|
extern TSS
|
||||||
|
; usize interrupt_rust_enter()
|
||||||
|
; 返回值用于为寄存器rax占位
|
||||||
|
interrupt_rust_enter:
|
||||||
|
; *(rsp - 8) = *(TSS + 36)
|
||||||
|
mov rax, [TSS + 36]
|
||||||
|
mov qword [rsp - 8], rax
|
||||||
|
; *(TSS + 36) = rsp - 8
|
||||||
|
mov rax, TSS
|
||||||
|
lea rax, [rax + 36]
|
||||||
|
mov [rax], rsp
|
||||||
|
sub qword [rax], 8
|
||||||
|
sti
|
||||||
|
ret
|
||||||
|
|
||||||
|
global interrupt_rust_leave
|
||||||
|
extern TSS
|
||||||
|
; usize interrupt_rust_leave()
|
||||||
|
; 返回值用于为寄存器rax占位
|
||||||
|
interrupt_rust_leave:
|
||||||
|
cli
|
||||||
|
; *(TSS + 36) = *(rsp - 8)
|
||||||
|
mov rax, [rsp - 8]
|
||||||
|
mov [TSS + 36], rax
|
||||||
|
ret
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod interrupt;
|
||||||
|
pub mod proc;
|
|
@ -0,0 +1,32 @@
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RegisterTexture {
|
||||||
|
es: u16,
|
||||||
|
ds: u16,
|
||||||
|
reserved: u32,
|
||||||
|
r15: u64,
|
||||||
|
r14: u64,
|
||||||
|
r13: u64,
|
||||||
|
r12: u64,
|
||||||
|
r11: u64,
|
||||||
|
r10: u64,
|
||||||
|
r9: u64,
|
||||||
|
r8: u64,
|
||||||
|
rdi: u64,
|
||||||
|
rsi: u64,
|
||||||
|
rdx: u64,
|
||||||
|
rbx: u64,
|
||||||
|
rcx: u64,
|
||||||
|
rax: u64,
|
||||||
|
rbp: u64,
|
||||||
|
rip: u64,
|
||||||
|
cs: u64,
|
||||||
|
rflags: u64,
|
||||||
|
rsp: u64,
|
||||||
|
ss: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ProcessTexture {
|
||||||
|
register: RegisterTexture,
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ extern "C" {
|
||||||
pub struct SystemTimeError(Duration);
|
pub struct SystemTimeError(Duration);
|
||||||
|
|
||||||
#[derive(Clone, Copy, Hash)]
|
#[derive(Clone, Copy, Hash)]
|
||||||
|
#[derive(Default)]
|
||||||
pub struct SystemTime {
|
pub struct SystemTime {
|
||||||
unix_time: usize,
|
unix_time: usize,
|
||||||
ns_time: usize,
|
ns_time: usize,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use alloc::vec;
|
use crate::libk::alloc::vec::Vec;
|
||||||
use alloc::vec::Vec;
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
clock::time::SystemTime,
|
clock::time::SystemTime,
|
||||||
|
@ -28,12 +27,12 @@ pub struct KernelLogger {
|
||||||
impl KernelLogger {
|
impl KernelLogger {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
fatal_queue: vec![],
|
fatal_queue: Vec::new(),
|
||||||
error_queue: vec![],
|
error_queue: Vec::new(),
|
||||||
warning_queue: vec![],
|
warning_queue: Vec::new(),
|
||||||
info_queue: vec![],
|
info_queue: Vec::new(),
|
||||||
debug_queue: vec![],
|
debug_queue: Vec::new(),
|
||||||
trace_queue: vec![],
|
trace_queue: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,105 +90,18 @@ impl KernelLogger {
|
||||||
self.trace_queue.push((SystemTime::now(), msg));
|
self.trace_queue.push((SystemTime::now(), msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter(&self, level: LoggerLevel) -> LogIterator {
|
pub fn iter(&self, _level: LoggerLevel) -> LogIterator {
|
||||||
let mut logs = vec![];
|
todo!()
|
||||||
match level {
|
|
||||||
LoggerLevel::Fatal => {
|
|
||||||
logs.push(&self.fatal_queue);
|
|
||||||
}
|
|
||||||
LoggerLevel::Error => {
|
|
||||||
logs.push(&self.fatal_queue);
|
|
||||||
logs.push(&self.error_queue);
|
|
||||||
}
|
|
||||||
LoggerLevel::Warning => {
|
|
||||||
logs.push(&self.fatal_queue);
|
|
||||||
logs.push(&self.error_queue);
|
|
||||||
logs.push(&self.warning_queue);
|
|
||||||
}
|
|
||||||
LoggerLevel::Info => {
|
|
||||||
logs.push(&self.fatal_queue);
|
|
||||||
logs.push(&self.error_queue);
|
|
||||||
logs.push(&self.warning_queue);
|
|
||||||
logs.push(&self.info_queue);
|
|
||||||
}
|
|
||||||
LoggerLevel::Debug => {
|
|
||||||
logs.push(&self.fatal_queue);
|
|
||||||
logs.push(&self.error_queue);
|
|
||||||
logs.push(&self.warning_queue);
|
|
||||||
logs.push(&self.info_queue);
|
|
||||||
logs.push(&self.debug_queue);
|
|
||||||
}
|
|
||||||
LoggerLevel::Trace => {
|
|
||||||
logs.push(&self.fatal_queue);
|
|
||||||
logs.push(&self.error_queue);
|
|
||||||
logs.push(&self.warning_queue);
|
|
||||||
logs.push(&self.info_queue);
|
|
||||||
logs.push(&self.debug_queue);
|
|
||||||
logs.push(&self.trace_queue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let mut res = vec![];
|
|
||||||
let mut indeces = Vec::new();
|
|
||||||
for _ in 0..logs.len() {
|
|
||||||
indeces.push(0usize);
|
|
||||||
}
|
|
||||||
let all_end = |indeces: &Vec<usize>, logs: &Vec<&Vec<(SystemTime, Message)>>| {
|
|
||||||
for i in 0..indeces.len() {
|
|
||||||
if indeces[i] < logs.len() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
};
|
|
||||||
while !all_end(&indeces, &logs) {
|
|
||||||
let mut min_ind = None;
|
|
||||||
let mut min = None;
|
|
||||||
for i in 0..indeces.len() {
|
|
||||||
if indeces[i] >= logs[i].len() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if let Some(minx) = min.as_mut() {
|
|
||||||
if logs[i][indeces[i]].0 < *minx {
|
|
||||||
*minx = logs[i][indeces[i]].0;
|
|
||||||
min_ind = Some(i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
min = Some(logs[i][indeces[i]].0);
|
|
||||||
min_ind = Some(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(mini) = min_ind {
|
|
||||||
res.push(&logs[mini][indeces[mini]]);
|
|
||||||
indeces[mini] += 1;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LogIterator { logs: res }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LogIterator<'a> {
|
pub struct LogIterator {
|
||||||
logs: Vec<&'a (SystemTime, Message)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for LogIterator<'a> {
|
impl Iterator for LogIterator {
|
||||||
type Item = Message;
|
type Item = Message;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let res = if let Some((time, msg)) = self.logs.first() {
|
todo!()
|
||||||
Some(
|
|
||||||
MessageBuilder::new()
|
|
||||||
.message(time)
|
|
||||||
.append(MessageBuilder::from_message(msg.clone()))
|
|
||||||
.build(),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
if let Some(_) = res {
|
|
||||||
self.logs.remove(0);
|
|
||||||
}
|
|
||||||
res
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,8 @@ void kmain(void *mb2_bootinfo)
|
||||||
// 初始化中断管理
|
// 初始化中断管理
|
||||||
interrupt_init();
|
interrupt_init();
|
||||||
|
|
||||||
|
int i = 1 / 0;
|
||||||
|
|
||||||
// 初始化系统调用
|
// 初始化系统调用
|
||||||
syscall_init();
|
syscall_init();
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,7 @@
|
||||||
use crate::message;
|
use crate::kernel::tty::tty::Tty;
|
||||||
|
|
||||||
use super::{
|
|
||||||
klog::{KernelLogger, LoggerLevel},
|
|
||||||
tty::tty::{BuilderFunctions::*, Color, Tty},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn kmain_rust() -> ! {
|
extern "C" fn kmain_rust() -> ! {
|
||||||
let tty = Tty::from_id(0).unwrap();
|
let tty = Tty::from_id(0).unwrap();
|
||||||
let mut logger = KernelLogger::new();
|
|
||||||
logger.info(message!(
|
|
||||||
Msg("Hello, "),
|
|
||||||
Msg("Metaverse"),
|
|
||||||
FgColor(Color::GREEN),
|
|
||||||
Msg("!\n")
|
|
||||||
));
|
|
||||||
for msg in logger.iter(LoggerLevel::Info) {
|
|
||||||
tty.print(msg);
|
|
||||||
}
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@ allocator_t *memm_allocator_new(void *start, usize length, usize type, usize pid
|
||||||
allocator_t *allocator = start;
|
allocator_t *allocator = start;
|
||||||
allocator->magic = MEMM_ALLOCATOR_MAGIC;
|
allocator->magic = MEMM_ALLOCATOR_MAGIC;
|
||||||
allocator->full = false;
|
allocator->full = false;
|
||||||
allocator->pid = 0;
|
|
||||||
allocator->size = length;
|
allocator->size = length;
|
||||||
allocator->type = type;
|
allocator->type = type;
|
||||||
switch (type)
|
switch (type)
|
||||||
|
@ -71,10 +70,6 @@ void memm_free(void *mem)
|
||||||
allocator_t *allocator = memory_manager.kernel_base_allocator;
|
allocator_t *allocator = memory_manager.kernel_base_allocator;
|
||||||
if (allocator->magic != MEMM_ALLOCATOR_MAGIC)
|
if (allocator->magic != MEMM_ALLOCATOR_MAGIC)
|
||||||
return;
|
return;
|
||||||
if (is_user_address((u64)mem))
|
|
||||||
{
|
|
||||||
mem = mem - allocator->userspace + (void *)allocator;
|
|
||||||
}
|
|
||||||
allocator->free(allocator->allocator_instance, mem);
|
allocator->free(allocator->allocator_instance, mem);
|
||||||
if (allocator->full)
|
if (allocator->full)
|
||||||
allocator->full = false;
|
allocator->full = false;
|
||||||
|
|
|
@ -6,9 +6,9 @@ use core::{
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn memm_kernel_allocate(size: usize) -> *mut u8;
|
fn memm_kernel_allocate(size: usize) -> *mut u8;
|
||||||
// pub fn memm_user_allocate(size: usize, pid: usize);
|
// pub fn memm_user_allocate(size: usize, pid: usize);
|
||||||
pub fn memm_free(mem: *mut u8);
|
fn memm_free(mem: *mut u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct KernelAllocator {}
|
pub struct KernelAllocator {}
|
||||||
|
@ -31,4 +31,4 @@ unsafe impl GlobalAlloc for KernelAllocator {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static KERNEL_ALLOCATOR: KernelAllocator = KernelAllocator {};
|
pub static KERNEL_ALLOCATOR: KernelAllocator = KernelAllocator {};
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
mod memm;
|
pub mod memm;
|
||||||
|
|
|
@ -3,4 +3,4 @@ pub mod klog;
|
||||||
pub mod main;
|
pub mod main;
|
||||||
pub mod memm;
|
pub mod memm;
|
||||||
pub mod tty;
|
pub mod tty;
|
||||||
pub mod sync;
|
pub mod arch;
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
pub mod rwlock;
|
|
|
@ -1,129 +0,0 @@
|
||||||
use core::{ops::{Deref, DerefMut}, ptr::null_mut};
|
|
||||||
|
|
||||||
use alloc::{vec, vec::Vec};
|
|
||||||
|
|
||||||
/// ## RwLock<T>
|
|
||||||
/// 读写锁
|
|
||||||
///
|
|
||||||
/// * 对于写入操作:
|
|
||||||
///
|
|
||||||
/// 锁没有占用时,获取锁,并执行闭包。
|
|
||||||
///
|
|
||||||
/// 当锁已经被占用,将闭包悬挂。
|
|
||||||
///
|
|
||||||
/// 释放锁时,将所有悬挂的闭包都执行。
|
|
||||||
///
|
|
||||||
/// 正在释放锁时,`write`方法返回`Err(())`
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let num = 6;
|
|
||||||
/// let num = RwLock::new(num);
|
|
||||||
/// if let Err(()) = num.write(
|
|
||||||
/// |n| *n = 10
|
|
||||||
/// ) {}
|
|
||||||
/// let numstr = format!("{}", num.read());
|
|
||||||
/// ````
|
|
||||||
pub struct RwLock<'a, T> {
|
|
||||||
obj: T,
|
|
||||||
locked: bool,
|
|
||||||
dealing_hanged: bool,
|
|
||||||
ptr: *mut RwLockWriteGuard<'a, T>,
|
|
||||||
hanging: Vec<&'a dyn Fn(&mut T)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<T> Send for RwLock<'_, T> {}
|
|
||||||
unsafe impl<T> Sync for RwLock<'_, T> {}
|
|
||||||
|
|
||||||
impl<'a, T> RwLock<'a, T> {
|
|
||||||
pub fn new(obj: T) -> Self {
|
|
||||||
Self {
|
|
||||||
obj,
|
|
||||||
locked: false,
|
|
||||||
dealing_hanged: false,
|
|
||||||
ptr: null_mut(),
|
|
||||||
hanging: vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read(&self) -> RwLockReadGuard<T> {
|
|
||||||
RwLockReadGuard { obj: &self.obj }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write(&'a mut self, f: &'a dyn Fn(&mut T)) -> Result<RwLockWriteGuard<T>, ()> {
|
|
||||||
if self.dealing_hanged {
|
|
||||||
Err(())
|
|
||||||
} else if !self.locked {
|
|
||||||
self.locked = true;
|
|
||||||
f(&mut self.obj);
|
|
||||||
let ptr = { self as *mut RwLock<'a, T> };
|
|
||||||
let obj = &mut self.obj;
|
|
||||||
let mut res = RwLockWriteGuard {
|
|
||||||
obj,
|
|
||||||
ptr,
|
|
||||||
must_deal_hang: false,
|
|
||||||
};
|
|
||||||
self.ptr = &mut res as *mut RwLockWriteGuard<'_, T>;
|
|
||||||
Ok(res)
|
|
||||||
} else {
|
|
||||||
self.hanging.push(f);
|
|
||||||
let ptr = { self as *mut RwLock<'a, T> };
|
|
||||||
let obj = &mut self.obj;
|
|
||||||
Ok(RwLockWriteGuard {
|
|
||||||
obj,
|
|
||||||
ptr,
|
|
||||||
must_deal_hang: false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RwLockReadGuard<'a, T> {
|
|
||||||
obj: &'a T,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> Deref for RwLockReadGuard<'a, T> {
|
|
||||||
type Target = T;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
self.obj
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> Drop for RwLockReadGuard<'a, T> {
|
|
||||||
fn drop(&mut self) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RwLockWriteGuard<'a, T> {
|
|
||||||
obj: &'a mut T,
|
|
||||||
ptr: *mut RwLock<'a, T>,
|
|
||||||
must_deal_hang: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> Deref for RwLockWriteGuard<'a, T> {
|
|
||||||
type Target = T;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
self.obj
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> DerefMut for RwLockWriteGuard<'a, T> {
|
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
||||||
self.obj
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> Drop for RwLockWriteGuard<'a, T> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if self.must_deal_hang {
|
|
||||||
let p = unsafe { &mut *self.ptr };
|
|
||||||
p.dealing_hanged = true;
|
|
||||||
for f in p.hanging.iter() {
|
|
||||||
f(self.obj);
|
|
||||||
}
|
|
||||||
p.hanging.clear();
|
|
||||||
p.dealing_hanged = false;
|
|
||||||
p.locked = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,46 +1,28 @@
|
||||||
pub mod tty;
|
pub mod tty;
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! message_msg {
|
|
||||||
() => {};
|
|
||||||
( $builder : expr, $e : expr) => {
|
|
||||||
$builder.message_mut($e);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! message_fgc {
|
|
||||||
() => {};
|
|
||||||
( $builder : expr, $e : expr) => {
|
|
||||||
$builder.foreground_color_mut($e);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! message_bgc {
|
|
||||||
() => {};
|
|
||||||
( $builder : expr, $e : expr ) => {
|
|
||||||
$builder.background_color_mut($e);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! message {
|
macro_rules! message {
|
||||||
( $( $e : expr ),* ) => {{
|
( $fmtter : expr ) => {{
|
||||||
|
use crate::kernel::tty::tty::MessageBuilder;
|
||||||
|
MessageBuilder::new()
|
||||||
|
.message($fmtter)
|
||||||
|
.build()
|
||||||
|
}};
|
||||||
|
( $fmtter : expr, $( $e : expr ),* ) => {{
|
||||||
use crate::{
|
use crate::{
|
||||||
kernel::tty::tty::{MessageBuilder, BuilderFunctions},
|
kernel::tty::tty::{
|
||||||
message_msg, message_fgc, message_bgc
|
MessageBuilder,
|
||||||
|
FmtMeta,
|
||||||
|
Color,
|
||||||
|
format_message
|
||||||
|
},
|
||||||
|
libk::alloc::vec::Vec,
|
||||||
};
|
};
|
||||||
let mut tmp_builder = MessageBuilder::new();
|
let mut formatter = $fmtter.chars().collect::<Vec<char>>();
|
||||||
|
let builder = MessageBuilder::new();
|
||||||
$(
|
$(
|
||||||
if let BuilderFunctions::Msg(e) = $e {
|
let builder = builder.append(format_message(&mut formatter, $e));
|
||||||
message_msg!(tmp_builder, e);
|
|
||||||
} else if let BuilderFunctions::FgColor(c) = $e {
|
|
||||||
message_fgc!(tmp_builder, c);
|
|
||||||
} else if let BuilderFunctions::BgColor(c) = $e {
|
|
||||||
message_bgc!(tmp_builder, c);
|
|
||||||
}
|
|
||||||
)*
|
)*
|
||||||
tmp_builder.build()
|
builder.build()
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,7 @@ inline static void scroll_buffer(
|
||||||
usize dist)
|
usize dist)
|
||||||
{
|
{
|
||||||
memcpy(buffer, buffer + width * pixsize * dist, (height - dist) * width * pixsize);
|
memcpy(buffer, buffer + width * pixsize * dist, (height - dist) * width * pixsize);
|
||||||
|
memset(buffer + (height - dist) * width * pixsize, 0, dist * width * pixsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static void putchar(
|
inline static void putchar(
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use core::ptr::null_mut;
|
use core::ptr::null_mut;
|
||||||
|
|
||||||
use alloc::{
|
use crate::libk::alloc::{
|
||||||
|
boxed::Box,
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
vec,
|
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ impl Tty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, Default)]
|
||||||
pub struct Color(pub u8, pub u8, pub u8);
|
pub struct Color(pub u8, pub u8, pub u8);
|
||||||
|
|
||||||
impl Color {
|
impl Color {
|
||||||
|
@ -169,7 +169,7 @@ pub struct Resolution {
|
||||||
pub height: usize,
|
pub height: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Default)]
|
||||||
pub struct MessageSection {
|
pub struct MessageSection {
|
||||||
msg: String,
|
msg: String,
|
||||||
fgcolor: Color,
|
fgcolor: Color,
|
||||||
|
@ -179,14 +179,14 @@ pub struct MessageSection {
|
||||||
/// ## Message
|
/// ## Message
|
||||||
///
|
///
|
||||||
/// 用`MessageBuilder`构造一个`Message`对象
|
/// 用`MessageBuilder`构造一个`Message`对象
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Default)]
|
||||||
pub struct Message(Vec<MessageSection>);
|
pub struct Message(Vec<MessageSection>);
|
||||||
|
|
||||||
impl ToString for Message {
|
impl ToString for Message {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
let mut res = String::new();
|
let mut res = String::new();
|
||||||
for MessageSection { msg, .. } in self.0.iter() {
|
for MessageSection { msg, .. } in self.0.iter() {
|
||||||
res += msg;
|
res += msg.clone();
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,7 @@ impl ToString for Message {
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use crate::kernel::tty::tty::BuilderFunctions::*;
|
/// use crate::kernel::tty::tty::BuilderFunctions::*;
|
||||||
///
|
///
|
||||||
/// message!(
|
/// message_raw!(
|
||||||
/// Msg("Hello, "),
|
/// Msg("Hello, "),
|
||||||
/// Msg("Metaverse"),
|
/// Msg("Metaverse"),
|
||||||
/// FgColor(Color::GREEN),
|
/// FgColor(Color::GREEN),
|
||||||
|
@ -233,8 +233,8 @@ pub struct MessageBuilder {
|
||||||
msg: Message,
|
msg: Message,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum BuilderFunctions<'a> {
|
pub enum BuilderFunctions<T: ToString> {
|
||||||
Msg(&'a str),
|
Msg(T),
|
||||||
FgColor(Color),
|
FgColor(Color),
|
||||||
BgColor(Color),
|
BgColor(Color),
|
||||||
}
|
}
|
||||||
|
@ -242,10 +242,14 @@ pub enum BuilderFunctions<'a> {
|
||||||
impl MessageBuilder {
|
impl MessageBuilder {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
msg: Message(vec![]),
|
msg: Message(Vec::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.msg.0.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_message(msg: Message) -> Self {
|
pub fn from_message(msg: Message) -> Self {
|
||||||
Self { msg }
|
Self { msg }
|
||||||
}
|
}
|
||||||
|
@ -302,3 +306,82 @@ impl MessageBuilder {
|
||||||
self.msg
|
self.msg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum FmtMeta {
|
||||||
|
Color(Color),
|
||||||
|
String(String),
|
||||||
|
ToStringable(Box<dyn ToString>),
|
||||||
|
Hex(u8),
|
||||||
|
Pointer(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_message(fmt: &mut Vec<char>, meta: FmtMeta) -> MessageBuilder {
|
||||||
|
let mut msgbuilder = MessageBuilder::new();
|
||||||
|
let mut fmt_start = None;
|
||||||
|
let mut fmt_end = None;
|
||||||
|
for i in 0..fmt.len() {
|
||||||
|
if fmt[i] == '{' {
|
||||||
|
fmt_start = Some(i);
|
||||||
|
}
|
||||||
|
if fmt[i] == '}' {
|
||||||
|
fmt_end = Some(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let tohex = |n: u8| {
|
||||||
|
if n < 10 {
|
||||||
|
(b'0' + n) as char
|
||||||
|
} else {
|
||||||
|
(b'a' + n - 10) as char
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if fmt_start == None || fmt_end == None {
|
||||||
|
msgbuilder.message_mut(&String::from_iter(fmt.iter()));
|
||||||
|
} else {
|
||||||
|
let fmt_start = fmt_start.unwrap();
|
||||||
|
let fmt_end = fmt_end.unwrap();
|
||||||
|
let mut formatter = Vec::new();
|
||||||
|
for _ in fmt_start..=fmt_end {
|
||||||
|
formatter.push(fmt.remove(fmt_start));
|
||||||
|
}
|
||||||
|
formatter.remove(formatter.len() - 1);
|
||||||
|
formatter.remove(0);
|
||||||
|
match meta {
|
||||||
|
FmtMeta::Color(color) => {
|
||||||
|
let first = fmt.split_at(fmt_start).0;
|
||||||
|
msgbuilder.message_mut(&String::from_iter(first.iter()));
|
||||||
|
for _ in 0..fmt_start {
|
||||||
|
fmt.remove(0);
|
||||||
|
}
|
||||||
|
msgbuilder.message_mut(&String::from_iter(formatter.iter()));
|
||||||
|
msgbuilder.foreground_color_mut(color);
|
||||||
|
}
|
||||||
|
FmtMeta::String(s) => {
|
||||||
|
for c in s.chars().rev() {
|
||||||
|
fmt.insert(fmt_start, *c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FmtMeta::ToStringable(s) => {
|
||||||
|
for c in s.to_string().chars().rev() {
|
||||||
|
fmt.insert(fmt_start, *c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FmtMeta::Hex(num) => {
|
||||||
|
fmt.insert(fmt_start, tohex(num >> 4));
|
||||||
|
fmt.insert(fmt_start, tohex(num & 0xf));
|
||||||
|
}
|
||||||
|
FmtMeta::Pointer(mut p) => {
|
||||||
|
for _ in 0..16 {
|
||||||
|
fmt.insert(fmt_start, tohex((p & 0xf) as u8));
|
||||||
|
p >>= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut rests = Vec::new();
|
||||||
|
while !fmt.is_empty() && fmt[0] != '{' {
|
||||||
|
rests.push(fmt.remove(0));
|
||||||
|
}
|
||||||
|
msgbuilder.message_mut(&String::from_iter(rests.iter()));
|
||||||
|
msgbuilder
|
||||||
|
}
|
||||||
|
|
66
src/lib.rs
66
src/lib.rs
|
@ -1,69 +1,23 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
#![feature(strict_provenance)]
|
||||||
|
#![feature(layout_for_ptr)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
use alloc::{
|
use core::panic::PanicInfo;
|
||||||
string::{String, ToString},
|
|
||||||
vec::Vec,
|
|
||||||
};
|
|
||||||
use core::{panic::PanicInfo, ptr::null_mut};
|
|
||||||
|
|
||||||
use kernel::tty::tty::{self, tty_enable, tty_text_print, Color};
|
use kernel::tty::tty::Tty;
|
||||||
|
|
||||||
pub mod kernel;
|
pub mod kernel;
|
||||||
pub mod libk;
|
pub mod libk;
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
unsafe fn kernel_panic_handler(info: &PanicInfo) -> ! {
|
unsafe fn kernel_panic_handler(_info: &PanicInfo) -> ! {
|
||||||
let line_in_file = if let Some(loca) = info.location() {
|
let tty = Tty::from_id(0).unwrap();
|
||||||
loca.line().to_string()
|
tty.enable();
|
||||||
} else {
|
tty.print(message!(
|
||||||
String::new()
|
"Hit a {Rust} panic.",
|
||||||
};
|
FmtMeta::Color(Color::ORANGE)
|
||||||
let info = {
|
|
||||||
let mut v = Vec::new();
|
|
||||||
v.push(("Kernel Panic: ", (Color::RED, Color::BLACK)));
|
|
||||||
v.push((
|
|
||||||
if let Some(loca) = info.location() {
|
|
||||||
loca.file()
|
|
||||||
} else {
|
|
||||||
"NoFile"
|
|
||||||
},
|
|
||||||
(Color::GREEN, Color::BLACK),
|
|
||||||
));
|
));
|
||||||
v.push((":", (Color::WHITE, Color::BLACK)));
|
|
||||||
v.push((
|
|
||||||
if let Some(_) = info.location() {
|
|
||||||
line_in_file.as_str()
|
|
||||||
} else {
|
|
||||||
"NoLine"
|
|
||||||
},
|
|
||||||
(Color::WHITE, Color::BLACK),
|
|
||||||
));
|
|
||||||
v.push((": ", (Color::WHITE, Color::BLACK)));
|
|
||||||
v.push((
|
|
||||||
if let Some(&s) = info.payload().downcast_ref::<&str>() {
|
|
||||||
s
|
|
||||||
} else {
|
|
||||||
"Unknown panic."
|
|
||||||
},
|
|
||||||
(Color::BLUE, Color::BLACK),
|
|
||||||
));
|
|
||||||
v.push(("\n", (Color::BLACK, Color::BLACK)));
|
|
||||||
v
|
|
||||||
};
|
|
||||||
let tty = tty::tty_get(0);
|
|
||||||
if tty != null_mut() {
|
|
||||||
let tty = *tty;
|
|
||||||
tty_enable(tty);
|
|
||||||
for (msgo, (fgc, bgc)) in info.into_iter() {
|
|
||||||
let msg = String::from(msgo).as_bytes_mut() as *mut [u8] as *mut u8;
|
|
||||||
let p = msg.offset(msgo.len() as isize);
|
|
||||||
let swp = *p;
|
|
||||||
*p = 0;
|
|
||||||
tty_text_print(tty, msg, u32::from(fgc), u32::from(bgc));
|
|
||||||
*p = swp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
use core::alloc::{GlobalAlloc, Layout};
|
||||||
|
|
||||||
|
use crate::kernel::memm::memm::KERNEL_ALLOCATOR;
|
||||||
|
|
||||||
|
pub unsafe fn alloc(layout: Layout) -> *mut u8 {
|
||||||
|
KERNEL_ALLOCATOR.alloc(layout)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) {
|
||||||
|
KERNEL_ALLOCATOR.dealloc(ptr, layout);
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
use core::{
|
||||||
|
alloc::Layout,
|
||||||
|
mem::transmute,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
ptr::addr_of,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::libk::alloc::alloc::{alloc, dealloc};
|
||||||
|
|
||||||
|
pub struct Box<T: ?Sized> {
|
||||||
|
inner: *mut T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Box<T> {
|
||||||
|
pub fn new(t: T) -> Self {
|
||||||
|
unsafe {
|
||||||
|
let inner = alloc(Layout::for_value(&t));
|
||||||
|
inner.copy_from(addr_of!(t).cast(), 1);
|
||||||
|
Self {
|
||||||
|
inner: transmute(inner),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized> Deref for Box<T> {
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
unsafe { self.inner.as_ref().unwrap() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized> DerefMut for Box<T> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
unsafe { self.inner.as_mut().unwrap() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized> Drop for Box<T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
dealloc(
|
||||||
|
self.inner.cast(),
|
||||||
|
Layout::for_value_raw(self.inner.cast_const()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
pub mod alloc;
|
||||||
|
pub mod boxed;
|
||||||
|
pub mod string;
|
||||||
|
pub mod vec;
|
|
@ -0,0 +1,386 @@
|
||||||
|
use core::ops::{Add, AddAssign};
|
||||||
|
|
||||||
|
use super::vec::{Vec, VecIterator};
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct String {
|
||||||
|
data: Vec<char>,
|
||||||
|
u8data: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl String {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
data: Vec::new(),
|
||||||
|
u8data: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.data.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn chars(&self) -> VecIterator<char> {
|
||||||
|
self.data.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_bytes(&self) -> &[u8] {
|
||||||
|
&self.u8data[..]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
|
||||||
|
&mut self.u8data[..]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, index: usize, item: char) {
|
||||||
|
self.data.insert(index, item);
|
||||||
|
self.u8data.insert(index, item as u8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromIterator<char> for String {
|
||||||
|
fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
|
||||||
|
let data = Vec::from_iter(iter);
|
||||||
|
let u8data = Vec::from_iter(data.iter().map(|c| *c as u8));
|
||||||
|
Self { data, u8data }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> FromIterator<&'a char> for String {
|
||||||
|
fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
|
||||||
|
let data = Vec::from_iter(iter.into_iter().map(|c| *c));
|
||||||
|
let u8data = Vec::from_iter(data.iter().map(|c| *c as u8));
|
||||||
|
Self { data, u8data }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for String {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
self.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add for String {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(mut self, rhs: Self) -> Self::Output {
|
||||||
|
self.data.append(&mut rhs.chars().map(|c| *c).collect());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddAssign for String {
|
||||||
|
fn add_assign(&mut self, rhs: String) {
|
||||||
|
*self = self.clone() + rhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for String {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
data: self.data.clone(),
|
||||||
|
u8data: self.u8data.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ToString {
|
||||||
|
fn to_string(&self) -> String;
|
||||||
|
fn to_octal_string(&self) -> String {
|
||||||
|
String::new()
|
||||||
|
}
|
||||||
|
fn to_hex_string(&self) -> String {
|
||||||
|
String::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for str {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
String::from_iter(self.chars())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for &'static str {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
(*self).to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for u8 {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 10) as u8 + b'0') as char);
|
||||||
|
num /= 10;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_octal_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 8) as u8 + b'0') as char);
|
||||||
|
num /= 8;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_hex_string(&self) -> String {
|
||||||
|
let tohex = |x| {
|
||||||
|
if x < 10 {
|
||||||
|
x as u8 + b'0'
|
||||||
|
} else {
|
||||||
|
x as u8 - 10 + b'a'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, tohex(num % 16) as char);
|
||||||
|
num /= 16;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for u16 {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 10) as u8 + b'0') as char);
|
||||||
|
num /= 10;
|
||||||
|
}
|
||||||
|
if res.len() == 0 {
|
||||||
|
res.insert(0, '0');
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_octal_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 8) as u8 + b'0') as char);
|
||||||
|
num /= 8;
|
||||||
|
}
|
||||||
|
if res.len() == 0 {
|
||||||
|
res.insert(0, '0');
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_hex_string(&self) -> String {
|
||||||
|
let tohex = |x| {
|
||||||
|
if x < 10 {
|
||||||
|
x as u8 + b'0'
|
||||||
|
} else {
|
||||||
|
x as u8 - 10 + b'a'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, tohex(num % 16) as char);
|
||||||
|
num /= 16;
|
||||||
|
}
|
||||||
|
if res.len() == 0 {
|
||||||
|
res.insert(0, '0');
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for u32 {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 10) as u8 + b'0') as char);
|
||||||
|
num /= 10;
|
||||||
|
}
|
||||||
|
if res.len() == 0 {
|
||||||
|
res.insert(0, '0');
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_octal_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 8) as u8 + b'0') as char);
|
||||||
|
num /= 8;
|
||||||
|
}
|
||||||
|
if res.len() == 0 {
|
||||||
|
res.insert(0, '0');
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_hex_string(&self) -> String {
|
||||||
|
let tohex = |x| {
|
||||||
|
if x < 10 {
|
||||||
|
x as u8 + b'0'
|
||||||
|
} else {
|
||||||
|
x as u8 - 10 + b'a'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, tohex(num % 16) as char);
|
||||||
|
num /= 16;
|
||||||
|
}
|
||||||
|
if res.len() == 0 {
|
||||||
|
res.insert(0, '0');
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for u64 {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 10) as u8 + b'0') as char);
|
||||||
|
num /= 10;
|
||||||
|
}
|
||||||
|
if res.len() == 0 {
|
||||||
|
res.insert(0, '0');
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_octal_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 8) as u8 + b'0') as char);
|
||||||
|
num /= 8;
|
||||||
|
}
|
||||||
|
if res.len() == 0 {
|
||||||
|
res.insert(0, '0');
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_hex_string(&self) -> String {
|
||||||
|
let tohex = |x| {
|
||||||
|
if x < 10 {
|
||||||
|
x as u8 + b'0'
|
||||||
|
} else {
|
||||||
|
x as u8 - 10 + b'a'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, tohex(num % 16) as char);
|
||||||
|
num /= 16;
|
||||||
|
}
|
||||||
|
if res.len() == 0 {
|
||||||
|
res.insert(0, '0');
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for u128 {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 10) as u8 + b'0') as char);
|
||||||
|
num /= 10;
|
||||||
|
}
|
||||||
|
if res.len() == 0 {
|
||||||
|
res.insert(0, '0');
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_octal_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 8) as u8 + b'0') as char);
|
||||||
|
num /= 8;
|
||||||
|
}
|
||||||
|
if res.len() == 0 {
|
||||||
|
res.insert(0, '0');
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_hex_string(&self) -> String {
|
||||||
|
let tohex = |x| {
|
||||||
|
if x < 10 {
|
||||||
|
x as u8 + b'0'
|
||||||
|
} else {
|
||||||
|
x as u8 - 10 + b'a'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, tohex(num % 16) as char);
|
||||||
|
num /= 16;
|
||||||
|
}
|
||||||
|
if res.len() == 0 {
|
||||||
|
res.insert(0, '0');
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for usize {
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 10) as u8 + b'0') as char);
|
||||||
|
num /= 10;
|
||||||
|
}
|
||||||
|
if res.len() == 0 {
|
||||||
|
res.insert(0, '0');
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_octal_string(&self) -> String {
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, ((num % 8) as u8 + b'0') as char);
|
||||||
|
num /= 8;
|
||||||
|
}
|
||||||
|
if res.len() == 0 {
|
||||||
|
res.insert(0, '0');
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_hex_string(&self) -> String {
|
||||||
|
let tohex = |x| {
|
||||||
|
if x < 10 {
|
||||||
|
x as u8 + b'0'
|
||||||
|
} else {
|
||||||
|
x as u8 - 10 + b'a'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut num = *self;
|
||||||
|
let mut res = String::new();
|
||||||
|
while num != 0 {
|
||||||
|
res.insert(0, tohex(num % 16) as char);
|
||||||
|
num /= 16;
|
||||||
|
}
|
||||||
|
if res.len() == 0 {
|
||||||
|
res.insert(0, '0');
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,284 @@
|
||||||
|
use core::{
|
||||||
|
alloc::Layout,
|
||||||
|
ops::{Index, IndexMut, Range, RangeFull},
|
||||||
|
ptr::addr_of_mut,
|
||||||
|
slice,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::libk::{
|
||||||
|
alloc::alloc::{alloc, dealloc},
|
||||||
|
core::ptr::PtrOptions,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Vec<T> {
|
||||||
|
pointer: *mut T,
|
||||||
|
length: usize,
|
||||||
|
capacity: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Vec<T> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
pointer: unsafe { alloc(Layout::array::<T>(4).unwrap()).cast() },
|
||||||
|
length: 0,
|
||||||
|
capacity: 4,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn extend_capacity(&mut self) {
|
||||||
|
let newp: *mut T = alloc(Layout::array::<T>(self.capacity * 2).unwrap()).cast();
|
||||||
|
self.pointer.kcopy_to(newp, self.length);
|
||||||
|
dealloc(
|
||||||
|
self.pointer.cast(),
|
||||||
|
Layout::array::<T>(self.capacity).unwrap(),
|
||||||
|
);
|
||||||
|
self.pointer = newp;
|
||||||
|
self.capacity *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push(&mut self, item: T) {
|
||||||
|
if self.capacity == self.length {
|
||||||
|
unsafe { self.extend_capacity() }
|
||||||
|
}
|
||||||
|
unsafe { self.pointer.offset(self.length as isize).write(item) };
|
||||||
|
self.length += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, index: usize, item: T) {
|
||||||
|
if self.capacity == self.length {
|
||||||
|
unsafe { self.extend_capacity() }
|
||||||
|
}
|
||||||
|
let rearlen = self.length - index;
|
||||||
|
unsafe {
|
||||||
|
if rearlen != 0 {
|
||||||
|
let tmp = alloc(Layout::array::<T>(rearlen).unwrap()).cast();
|
||||||
|
self.pointer.offset(index as isize).kcopy_to(tmp, rearlen);
|
||||||
|
self.pointer.offset(index as isize).write(item);
|
||||||
|
self.pointer
|
||||||
|
.offset(index as isize + 1)
|
||||||
|
.kcopy_from(tmp, rearlen);
|
||||||
|
} else {
|
||||||
|
self.pointer.offset(self.length as isize).write(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.length += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn append(&mut self, v: &mut Self) {
|
||||||
|
while self.capacity < self.length + v.length {
|
||||||
|
unsafe { self.extend_capacity() }
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
self.pointer
|
||||||
|
.offset(self.length as isize)
|
||||||
|
.kcopy_from(v.pointer.cast_const(), v.length)
|
||||||
|
};
|
||||||
|
self.length += v.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn split_at(&self, index: usize) -> (&[T], &[T]) {
|
||||||
|
if index >= self.length {
|
||||||
|
panic!("Index out of bound.");
|
||||||
|
}
|
||||||
|
(&self[0..index], &self[index..self.length])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.length
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.length == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn last_mut(&mut self) -> Option<&mut T> {
|
||||||
|
unsafe { self.pointer.offset(self.length as isize - 1).as_mut() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn last(&self) -> Option<&T> {
|
||||||
|
unsafe { self.pointer.offset(self.length as isize - 1).as_ref() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove(&mut self, index: usize) -> T {
|
||||||
|
if index >= self.length {
|
||||||
|
panic!("Index out of bound.");
|
||||||
|
}
|
||||||
|
let mut t: T = T::default();
|
||||||
|
let pt = addr_of_mut!(t);
|
||||||
|
unsafe {
|
||||||
|
pt.kcopy_from(self.pointer.offset(index as isize).cast_const(), 1);
|
||||||
|
self.pointer.offset(index as isize).kcopy_from(
|
||||||
|
self.pointer.offset(index as isize + 1),
|
||||||
|
self.length - index - 1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
self.length -= 1;
|
||||||
|
t
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> VecIterator<T> {
|
||||||
|
VecIterator {
|
||||||
|
pointer: self.pointer,
|
||||||
|
index: 0,
|
||||||
|
length: self.length,
|
||||||
|
_phantom: &(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Default for Vec<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Index<usize> for Vec<T> {
|
||||||
|
type Output = T;
|
||||||
|
|
||||||
|
fn index(&self, index: usize) -> &Self::Output {
|
||||||
|
unsafe { self.pointer.offset(index as isize).as_ref().unwrap() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Index<Range<usize>> for Vec<T> {
|
||||||
|
type Output = [T];
|
||||||
|
|
||||||
|
fn index(&self, index: Range<usize>) -> &Self::Output {
|
||||||
|
unsafe { &slice::from_raw_parts_mut(self.pointer, self.length)[index] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Index<RangeFull> for Vec<T> {
|
||||||
|
type Output = [T];
|
||||||
|
|
||||||
|
fn index(&self, _: RangeFull) -> &Self::Output {
|
||||||
|
unsafe { slice::from_raw_parts(self.pointer.cast(), self.length) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> IndexMut<RangeFull> for Vec<T> {
|
||||||
|
fn index_mut(&mut self, _: RangeFull) -> &mut Self::Output {
|
||||||
|
unsafe { slice::from_raw_parts_mut(self.pointer.cast(), self.length) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Clone for Vec<T> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
let res = Self {
|
||||||
|
pointer: unsafe { alloc(Layout::array::<T>(self.capacity).unwrap()).cast() },
|
||||||
|
length: self.length,
|
||||||
|
capacity: self.capacity,
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
res.pointer
|
||||||
|
.kcopy_from(self.pointer.cast_const(), self.length)
|
||||||
|
};
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Drop for Vec<T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
dealloc(
|
||||||
|
self.pointer.cast(),
|
||||||
|
Layout::array::<T>(self.capacity).unwrap(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> FromIterator<T> for Vec<T> {
|
||||||
|
fn from_iter<U: IntoIterator<Item = T>>(iter: U) -> Self {
|
||||||
|
let mut res = Vec::new();
|
||||||
|
for i in iter {
|
||||||
|
res.push(i);
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> IntoIterator for Vec<T> {
|
||||||
|
type Item = T;
|
||||||
|
|
||||||
|
type IntoIter = VecIter<T>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
VecIter {
|
||||||
|
pointer: self.pointer,
|
||||||
|
index: 0,
|
||||||
|
length: self.length,
|
||||||
|
capacity: self.capacity,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct VecIterator<'a, T> {
|
||||||
|
pointer: *mut T,
|
||||||
|
index: usize,
|
||||||
|
length: usize,
|
||||||
|
_phantom: &'a (),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: 'a> Iterator for VecIterator<'a, T> {
|
||||||
|
type Item = &'a T;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.index == self.length {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let res = unsafe { Some(self.pointer.offset(self.index as isize).as_ref().unwrap()) };
|
||||||
|
self.index += 1;
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: 'a> DoubleEndedIterator for VecIterator<'a, T> {
|
||||||
|
fn next_back(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.index == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
self.index -= 1;
|
||||||
|
unsafe { Some(self.pointer.offset(self.index as isize).as_ref().unwrap()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct VecIter<T> {
|
||||||
|
pointer: *mut T,
|
||||||
|
index: usize,
|
||||||
|
length: usize,
|
||||||
|
capacity: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Iterator for VecIter<T> {
|
||||||
|
type Item = T;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.index == self.length {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let mut t = T::default();
|
||||||
|
let res = unsafe {
|
||||||
|
self.pointer
|
||||||
|
.offset(self.index as isize)
|
||||||
|
.kcopy_to(addr_of_mut!(t), 1);
|
||||||
|
Some(t)
|
||||||
|
};
|
||||||
|
self.index += 1;
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Drop for VecIter<T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
dealloc(
|
||||||
|
self.pointer.cast(),
|
||||||
|
Layout::array::<T>(self.capacity).unwrap(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod ptr;
|
|
@ -0,0 +1,30 @@
|
||||||
|
use core::mem::{size_of, transmute};
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
pub fn memset(des: *const u8, src: u8, len: usize);
|
||||||
|
pub fn memcpy(des: *const u8, src: *const u8, len: usize);
|
||||||
|
pub fn strlen(des: *const u8) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PtrOptions<T> {
|
||||||
|
unsafe fn kcopy_from(self, src: *const T, count: usize);
|
||||||
|
unsafe fn kcopy_to(self, des: *const T, count: usize);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PtrOptions<T> for *mut T {
|
||||||
|
unsafe fn kcopy_from(self, src: *const T, count: usize) {
|
||||||
|
memcpy(
|
||||||
|
transmute(self.cast_const()),
|
||||||
|
transmute(src),
|
||||||
|
count * size_of::<T>(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn kcopy_to(self, des: *const T, count: usize) {
|
||||||
|
memcpy(
|
||||||
|
transmute(des),
|
||||||
|
transmute(self.cast_const()),
|
||||||
|
count * size_of::<T>(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1,2 @@
|
||||||
pub mod string;
|
pub mod alloc;
|
||||||
|
pub mod core;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue