增加内核日志功能 #3
|
@ -1,3 +1,3 @@
|
||||||
[submodule "rustlib"]
|
[submodule "rustlib"]
|
||||||
path = rustlib
|
path = rustlib
|
||||||
url = http://git.suthby.org:2024/metaverse/kernel-release.git
|
url = http://git.suthby.org:2024/metaverse/rustenv
|
||||||
|
|
|
@ -2,3 +2,9 @@
|
||||||
name = "metaverse"
|
name = "metaverse"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
# 此Cargo.toml仅用于rust-analyzer识别rust部分的代码
|
||||||
|
# 不应使用cargo编译
|
||||||
|
|
||||||
|
[target.'cfg(target_arch = "x86_64")']
|
||||||
|
target = "x86_64-unknown-none"
|
||||||
|
|
|
@ -56,7 +56,7 @@ make debug
|
||||||
* [x] 内存分配器
|
* [x] 内存分配器
|
||||||
* [x] raw_allocator
|
* [x] raw_allocator
|
||||||
* [x] tty
|
* [x] tty
|
||||||
* [ ] 内核日志
|
* [x] 内核日志
|
||||||
* [ ] 文件系统
|
* [ ] 文件系统
|
||||||
* [ ] vfs
|
* [ ] vfs
|
||||||
* [ ] fat32驱动(移植)
|
* [ ] fat32驱动(移植)
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef TIME_H
|
||||||
|
#define TIME_H
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
// 使用UNIX时间戳
|
||||||
|
usize system_time_get();
|
||||||
|
|
||||||
|
// 如果硬件支持更高的计时精度,
|
||||||
|
// 此函数提供从系统unix时间开始到现在的纳秒为单位的时间
|
||||||
|
usize system_time_ns_get();
|
||||||
|
|
||||||
|
void system_time_increase();
|
||||||
|
|
||||||
|
#endif
|
|
@ -139,9 +139,13 @@ allocator对象在进程与内核之间传递时一律使用内核空间的映
|
||||||
*/
|
*/
|
||||||
void *memm_allocate(usize size, usize pid);
|
void *memm_allocate(usize size, usize pid);
|
||||||
#define memm_addr_set_allocator(mem, allocator) \
|
#define memm_addr_set_allocator(mem, allocator) \
|
||||||
*(allocator_t **)(mem - 16) = allocator;
|
*(allocator_t **)((void *)(mem) - 16) = allocator;
|
||||||
#define memm_addr_get_allocator(mem) \
|
#define memm_addr_get_allocator(mem) \
|
||||||
((*(allocator_t **)(mem - 16)))
|
((*(allocator_t **)((void *)(mem) - 16)))
|
||||||
|
|
||||||
|
void *memm_kernel_allocate(usize size);
|
||||||
|
|
||||||
|
void *memm_user_allocate(usize size, usize pid);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
释放内存
|
释放内存
|
||||||
|
|
|
@ -6,13 +6,13 @@
|
||||||
|
|
||||||
typedef enum __tty_type
|
typedef enum __tty_type
|
||||||
{
|
{
|
||||||
invalid = 0,
|
tty_type_invalid = 0,
|
||||||
// 用于在内核刚刚被引导,只有bootloader提供的显示功能时使用
|
// 用于在内核刚刚被引导,只有bootloader提供的显示功能时使用
|
||||||
tty_type_raw_framebuffer = 1,
|
tty_type_raw_framebuffer = 1,
|
||||||
// 用于图形功能初始化后,直接连接图形接口
|
// 用于图形功能初始化后,直接连接图形接口
|
||||||
tty_type_display = 2,
|
tty_type_display = 2,
|
||||||
// 用于图形终端的终端模拟器
|
// 用于图形终端的终端模拟器
|
||||||
tty_type_vtty = 3,
|
tty_type_vterm = 3,
|
||||||
} tty_type;
|
} tty_type;
|
||||||
|
|
||||||
typedef enum __framebuffer_pixel_type
|
typedef enum __framebuffer_pixel_type
|
||||||
|
@ -40,8 +40,9 @@ typedef struct __framebuffer framebuffer;
|
||||||
// 文本模式中的字符由tty模块渲染
|
// 文本模式中的字符由tty模块渲染
|
||||||
typedef enum __tty_mode
|
typedef enum __tty_mode
|
||||||
{
|
{
|
||||||
tty_mode_text = 0,
|
tty_mode_invalid = 0,
|
||||||
tty_mode_graphics = 1,
|
tty_mode_text = 1,
|
||||||
|
tty_mode_graphics = 2,
|
||||||
} tty_mode;
|
} tty_mode;
|
||||||
|
|
||||||
typedef struct __tty_text_state
|
typedef struct __tty_text_state
|
||||||
|
@ -55,9 +56,11 @@ typedef struct __tty_text_state
|
||||||
typedef struct __tty
|
typedef struct __tty
|
||||||
{
|
{
|
||||||
usize id;
|
usize id;
|
||||||
|
usize width, height;
|
||||||
tty_type type;
|
tty_type type;
|
||||||
tty_typeinfo typeinfo;
|
tty_typeinfo typeinfo;
|
||||||
tty_mode mode;
|
tty_mode mode;
|
||||||
|
bool enabled;
|
||||||
tty_text_state text;
|
tty_text_state text;
|
||||||
} tty;
|
} tty;
|
||||||
|
|
||||||
|
@ -67,6 +70,7 @@ typedef struct __tty_controller_t
|
||||||
#define TTY_MAX_NUM 128
|
#define TTY_MAX_NUM 128
|
||||||
tty *ttys[TTY_MAX_NUM];
|
tty *ttys[TTY_MAX_NUM];
|
||||||
bool map[TTY_MAX_NUM];
|
bool map[TTY_MAX_NUM];
|
||||||
|
tty *enabled[TTY_MAX_NUM];
|
||||||
} tty_controller_t;
|
} tty_controller_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,6 +122,26 @@ void tty_text_print(tty *ttyx, char *string, u32 color, u32 bgcolor);
|
||||||
|
|
||||||
#define gen_color(r, g, b) (((r) << 16) | ((g) << 8) | (b))
|
#define gen_color(r, g, b) (((r) << 16) | ((g) << 8) | (b))
|
||||||
|
|
||||||
|
usize tty_get_width(tty *ttyx);
|
||||||
|
usize tty_get_height(tty *ttyx);
|
||||||
|
|
||||||
|
tty_type tty_get_type(tty *ttyx);
|
||||||
|
tty_mode tty_get_mode(tty *ttyx);
|
||||||
|
|
||||||
|
bool tty_is_enabled(tty *ttyx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 打开某个tty
|
||||||
|
*
|
||||||
|
* @param ttyx
|
||||||
|
* @return true 打开成功
|
||||||
|
* @return false 已经打开
|
||||||
|
* 或作为raw_framebuffer类型的tty,framebuffer已被其它raw_framebuffer
|
||||||
|
* 类型的tty占用
|
||||||
|
*/
|
||||||
|
bool tty_enable(tty *ttyx);
|
||||||
|
void tty_disable(tty *ttyx);
|
||||||
|
|
||||||
#define TTY_FONT_SCALE 2
|
#define TTY_FONT_SCALE 2
|
||||||
|
|
||||||
typedef struct __tty_font_t
|
typedef struct __tty_font_t
|
||||||
|
|
2
rustlib
2
rustlib
|
@ -1 +1 @@
|
||||||
Subproject commit f8d0d53a23b5a91848d8f6491122b69f79994537
|
Subproject commit 087c4795bbc23cd0baee060bda8c1159a971a542
|
29
src/Makefile
29
src/Makefile
|
@ -22,28 +22,29 @@ endif
|
||||||
################################
|
################################
|
||||||
# rust语言环境变量
|
# rust语言环境变量
|
||||||
|
|
||||||
RSCFLAGS = --emit obj --crate-type lib \
|
RSCFLAGS = --emit obj --crate-type staticlib --verbose \
|
||||||
|
--crate-name=metaverse \
|
||||||
|
--edition 2021 \
|
||||||
-L crate="${PWD}/../rustlib/${ARCH}/src/" \
|
-L crate="${PWD}/../rustlib/${ARCH}/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 opt-level=z
|
|
||||||
|
|
||||||
ifeq (${ARCH},x86_64)
|
ifeq (${ARCH},x86_64)
|
||||||
RSCFLAGS := ${RSCFLAGS} -C target-feature=-sse,-avx
|
RSCFLAGS := ${RSCFLAGS} --target x86_64-unknown-none
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef release
|
||||||
|
RSCFLAGS := -O
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq (${ARCH},x86_64)
|
||||||
|
RSCFLAGS := ${RSCFLAGS} -C target-feature=-sse
|
||||||
endif
|
endif
|
||||||
|
|
||||||
RUSTLIB_PATH = ../rustlib/${ARCH}/lib
|
RUSTLIB_PATH = ../rustlib/${ARCH}/lib
|
||||||
RUST_LIBS = "${RUSTLIB_PATH}/libaddr2line.rlib" "${RUSTLIB_PATH}/libadler.rlib" \
|
RUST_LIBS = "${RUSTLIB_PATH}/liballoc.rlib" "${RUSTLIB_PATH}/libcompiler_builtins.rlib" \
|
||||||
"${RUSTLIB_PATH}/liballoc.rlib" "${RUSTLIB_PATH}/libcfg_if.rlib" "${RUSTLIB_PATH}/libcompiler_builtins.rlib" \
|
"${RUSTLIB_PATH}/libcore.rlib" "${RUSTLIB_PATH}/librustc_std_workspace_core.rlib"
|
||||||
"${RUSTLIB_PATH}/libcore.rlib" "${RUSTLIB_PATH}/libgetopts.rlib" "${RUSTLIB_PATH}/libgimli.rlib" \
|
|
||||||
"${RUSTLIB_PATH}/libhashbrown.rlib" "${RUSTLIB_PATH}/libmemchr.rlib" "${RUSTLIB_PATH}/libminiz_oxide.rlib" \
|
|
||||||
"${RUSTLIB_PATH}/libobject.rlib" "${RUSTLIB_PATH}/libpanic_abort.rlib" "${RUSTLIB_PATH}/libpanic_unwind.rlib" \
|
|
||||||
"${RUSTLIB_PATH}/libproc_macro.rlib" "${RUSTLIB_PATH}/libprofiler_builtins.rlib" \
|
|
||||||
"${RUSTLIB_PATH}/librustc_demangle.rlib" "${RUSTLIB_PATH}/librustc_std_workspace_alloc.rlib" \
|
|
||||||
"${RUSTLIB_PATH}/librustc_std_workspace_core.rlib" "${RUSTLIB_PATH}/librustc_std_workspace_std.rlib" \
|
|
||||||
"${RUSTLIB_PATH}/libstd_detect.rlib" "${RUSTLIB_PATH}/libstd.rlib" "${RUSTLIB_PATH}/libsysroot.rlib" \
|
|
||||||
"${RUSTLIB_PATH}/libtest.rlib" "${RUSTLIB_PATH}/libunicode_width.rlib" "${RUSTLIB_PATH}/libunwind.rlib"
|
|
||||||
|
|
||||||
################################
|
################################
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,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
|
C_SRCS = main.c tty.c font.c memm.c memm_${ARCH}.c raw.c time.c
|
||||||
C_OBJS = ${C_SRCS:.c=.c.o}
|
C_OBJS = ${C_SRCS:.c=.c.o}
|
||||||
|
|
||||||
################################
|
################################
|
||||||
|
@ -38,7 +38,7 @@ STRIP_SECS = -R .note.GNU-stack
|
||||||
OBJCOPY_FLAGS = ${STRIP_SECS}
|
OBJCOPY_FLAGS = ${STRIP_SECS}
|
||||||
|
|
||||||
# 子目录
|
# 子目录
|
||||||
VPATH = memm/ memm/allocator tty/ klog/ arch/${ARCH}
|
VPATH = memm/ memm/allocator tty/ klog/ arch/${ARCH} clock/
|
||||||
|
|
||||||
%.c.o: %.c
|
%.c.o: %.c
|
||||||
@echo -e "\e[1m\e[33m${CC}\e[0m \e[32m$<\e[0m \e[34m-->\e[0m \e[1m\e[32m$@\e[0m"
|
@echo -e "\e[1m\e[33m${CC}\e[0m \e[32m$<\e[0m \e[34m-->\e[0m \e[1m\e[32m$@\e[0m"
|
||||||
|
|
|
@ -39,10 +39,6 @@ multiboot2_header:
|
||||||
dd 8
|
dd 8
|
||||||
multiboot2_header_end:
|
multiboot2_header_end:
|
||||||
|
|
||||||
section .kstack
|
|
||||||
kstack:
|
|
||||||
resb 0x1000000 - 0x400000
|
|
||||||
|
|
||||||
section .kend
|
section .kend
|
||||||
global kend
|
global kend
|
||||||
kend:
|
kend:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod time;
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include <kernel/clock/time.h>
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
usize system_time;
|
||||||
|
usize system_time_ns;
|
||||||
|
|
||||||
|
usize system_time_get()
|
||||||
|
{
|
||||||
|
return system_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
usize system_time_ns_get()
|
||||||
|
{
|
||||||
|
return system_time_ns;
|
||||||
|
}
|
||||||
|
|
||||||
|
void system_time_increase()
|
||||||
|
{
|
||||||
|
system_time++;
|
||||||
|
}
|
|
@ -0,0 +1,166 @@
|
||||||
|
use core::{cmp::Ordering, ops::Sub, time::Duration};
|
||||||
|
|
||||||
|
use alloc::{format, string::ToString};
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn system_time_get() -> usize;
|
||||||
|
fn system_time_ns_get() -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct SystemTimeError(Duration);
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Hash)]
|
||||||
|
pub struct SystemTime {
|
||||||
|
unix_time: usize,
|
||||||
|
ns_time: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for SystemTime {
|
||||||
|
fn to_string(&self) -> alloc::string::String {
|
||||||
|
let second_dur = 1000usize;
|
||||||
|
let minute_dur = second_dur * 60;
|
||||||
|
let hour_dur = minute_dur * 60;
|
||||||
|
let day_dur = hour_dur * 24;
|
||||||
|
let year_dur = day_dur * 365;
|
||||||
|
let four_year_dur = day_dur * (365 * 4 + 1);
|
||||||
|
|
||||||
|
let year = 1970
|
||||||
|
+ self.unix_time / four_year_dur * 4
|
||||||
|
+ if self.unix_time % four_year_dur < day_dur * 59 {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
(self.unix_time % four_year_dur - day_dur) / year_dur
|
||||||
|
};
|
||||||
|
let rest = self.unix_time % four_year_dur;
|
||||||
|
let mut leap = false;
|
||||||
|
let rest = if rest < day_dur * 59 {
|
||||||
|
rest
|
||||||
|
} else {
|
||||||
|
if rest < 60 {
|
||||||
|
leap = true;
|
||||||
|
}
|
||||||
|
rest - day_dur
|
||||||
|
};
|
||||||
|
let month = rest % year_dur;
|
||||||
|
let mut day = 0;
|
||||||
|
let month = if month < 31 * day_dur {
|
||||||
|
day = month;
|
||||||
|
1
|
||||||
|
} else if month < (31 + 28) * day_dur {
|
||||||
|
day = month - 31 * day_dur;
|
||||||
|
2
|
||||||
|
} else if month < (31 + 28 + 31) * day_dur {
|
||||||
|
day = month - (31 + 28) * day_dur;
|
||||||
|
3
|
||||||
|
} else if month < (31 + 28 + 31 + 30) * day_dur {
|
||||||
|
day = month - (31 + 28 + 31) * day_dur;
|
||||||
|
4
|
||||||
|
} else if month < (31 + 28 + 31 + 30 + 31) * day_dur {
|
||||||
|
day = month - (31 + 28 + 31 + 30) * day_dur;
|
||||||
|
5
|
||||||
|
} else if month < (31 + 28 + 31 + 30 + 31 + 30) * day_dur {
|
||||||
|
day = month - (31 + 28 + 31 + 30 + 31) * day_dur;
|
||||||
|
6
|
||||||
|
} else if month < (31 + 28 + 31 + 30 + 31 + 30 + 31) * day_dur {
|
||||||
|
day = month - (31 + 28 + 31 + 30 + 31 + 30) * day_dur;
|
||||||
|
7
|
||||||
|
} else if month < (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31) * day_dur {
|
||||||
|
day = month - (31 + 28 + 31 + 30 + 31 + 30 + 31) * day_dur;
|
||||||
|
8
|
||||||
|
} else if month < (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30) * day_dur {
|
||||||
|
day = month - (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31) * day_dur;
|
||||||
|
9
|
||||||
|
} else if month < (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31) * day_dur {
|
||||||
|
day = month - (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30) * day_dur;
|
||||||
|
10
|
||||||
|
} else if month < (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30) * day_dur {
|
||||||
|
day = month - (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31) * day_dur;
|
||||||
|
11
|
||||||
|
} else if month < (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31) * day_dur {
|
||||||
|
day = month - (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30) * day_dur;
|
||||||
|
12
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
let mut hour = day % day_dur;
|
||||||
|
day /= day_dur;
|
||||||
|
day += 1;
|
||||||
|
if leap {
|
||||||
|
day += 1;
|
||||||
|
}
|
||||||
|
let mut minute = hour % hour_dur;
|
||||||
|
hour /= hour_dur;
|
||||||
|
let mut second = minute % minute_dur;
|
||||||
|
minute /= minute_dur;
|
||||||
|
let milisec = second % second_dur;
|
||||||
|
second /= second_dur;
|
||||||
|
format!(
|
||||||
|
"[ {}-{}-{} {}:{}:{}.{} ] ",
|
||||||
|
year, month, day, hour, minute, second, milisec
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for SystemTime {}
|
||||||
|
impl PartialEq for SystemTime {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.unix_time == other.unix_time && self.ns_time == other.ns_time
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for SystemTime {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
match self.unix_time.cmp(&other.unix_time) {
|
||||||
|
Ordering::Equal => self.ns_time.cmp(&other.ns_time),
|
||||||
|
ord => ord,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for SystemTime {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
match self.unix_time.partial_cmp(&other.unix_time) {
|
||||||
|
Some(Ordering::Equal) => self.ns_time.partial_cmp(&other.ns_time),
|
||||||
|
ord => ord,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub<SystemTime> for SystemTime {
|
||||||
|
type Output = Result<Duration, SystemTimeError>;
|
||||||
|
|
||||||
|
fn sub(self, rhs: SystemTime) -> Self::Output {
|
||||||
|
if self < rhs {
|
||||||
|
let earl = (rhs - self).unwrap();
|
||||||
|
Err(SystemTimeError(earl))
|
||||||
|
} else {
|
||||||
|
let usdiff = self.ns_time as isize - self.ns_time as isize;
|
||||||
|
let usdiff = if usdiff >= 0 {
|
||||||
|
Duration::from_nanos(usdiff as usize as u64)
|
||||||
|
} else {
|
||||||
|
Duration::from_nanos(0) - Duration::from_nanos((-usdiff) as usize as u64)
|
||||||
|
};
|
||||||
|
Ok(Duration::from_millis((self.unix_time - rhs.unix_time) as u64) + usdiff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SystemTime {
|
||||||
|
pub fn now() -> Self {
|
||||||
|
unsafe {
|
||||||
|
Self {
|
||||||
|
unix_time: system_time_get(),
|
||||||
|
ns_time: system_time_ns_get(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn duration_since(&self, earlier: &SystemTime) -> Result<Duration, SystemTimeError> {
|
||||||
|
*self - *earlier
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn elapsed(&self) -> Result<Duration, SystemTimeError> {
|
||||||
|
SystemTime::now() - *self
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,196 @@
|
||||||
|
use alloc::string::ToString;
|
||||||
|
use alloc::vec;
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
clock::time::SystemTime,
|
||||||
|
tty::tty::{Color, Message, MessageBuilder},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
pub enum LoggerLevel {
|
||||||
|
Fatal,
|
||||||
|
Error,
|
||||||
|
Warning,
|
||||||
|
Info,
|
||||||
|
Debug,
|
||||||
|
Trace,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct KernelLogger {
|
||||||
|
fatal_queue: Vec<(SystemTime, Message)>,
|
||||||
|
error_queue: Vec<(SystemTime, Message)>,
|
||||||
|
warning_queue: Vec<(SystemTime, Message)>,
|
||||||
|
info_queue: Vec<(SystemTime, Message)>,
|
||||||
|
debug_queue: Vec<(SystemTime, Message)>,
|
||||||
|
trace_queue: Vec<(SystemTime, Message)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KernelLogger {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
fatal_queue: vec![],
|
||||||
|
error_queue: vec![],
|
||||||
|
warning_queue: vec![],
|
||||||
|
info_queue: vec![],
|
||||||
|
debug_queue: vec![],
|
||||||
|
trace_queue: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fatal(&mut self, msg: Message) {
|
||||||
|
let msg = MessageBuilder::new()
|
||||||
|
.message("Fatal: ")
|
||||||
|
.foreground_color(Color::RED)
|
||||||
|
.append(MessageBuilder::from_message(msg))
|
||||||
|
.build();
|
||||||
|
self.fatal_queue.push((SystemTime::now(), msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn error(&mut self, msg: Message) {
|
||||||
|
let msg = MessageBuilder::new()
|
||||||
|
.message("Error: ")
|
||||||
|
.foreground_color(Color::ORANGE)
|
||||||
|
.append(MessageBuilder::from_message(msg))
|
||||||
|
.build();
|
||||||
|
self.error_queue.push((SystemTime::now(), msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn warning(&mut self, msg: Message) {
|
||||||
|
let msg = MessageBuilder::new()
|
||||||
|
.message("Warning: ")
|
||||||
|
.foreground_color(Color::PURPLE)
|
||||||
|
.append(MessageBuilder::from_message(msg))
|
||||||
|
.build();
|
||||||
|
self.warning_queue.push((SystemTime::now(), msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn info(&mut self, msg: Message) {
|
||||||
|
let msg = MessageBuilder::new()
|
||||||
|
.message("Info: ")
|
||||||
|
.foreground_color(Color::GREEN)
|
||||||
|
.append(MessageBuilder::from_message(msg))
|
||||||
|
.build();
|
||||||
|
self.info_queue.push((SystemTime::now(), msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn debug(&mut self, msg: Message) {
|
||||||
|
let msg = MessageBuilder::new()
|
||||||
|
.message("Debug: ")
|
||||||
|
.foreground_color(Color::WHITE)
|
||||||
|
.append(MessageBuilder::from_message(msg))
|
||||||
|
.build();
|
||||||
|
self.debug_queue.push((SystemTime::now(), msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn trace(&mut self, msg: Message) {
|
||||||
|
let msg = MessageBuilder::new()
|
||||||
|
.message("Trace: ")
|
||||||
|
.foreground_color(Color::WHITE)
|
||||||
|
.append(MessageBuilder::from_message(msg))
|
||||||
|
.build();
|
||||||
|
self.trace_queue.push((SystemTime::now(), msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self, level: LoggerLevel) -> LogIterator {
|
||||||
|
let mut logs = vec![];
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 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> {
|
||||||
|
logs: Vec<&'a (SystemTime, Message)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for LogIterator<'a> {
|
||||||
|
type Item = Message;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let res = if let Some((time, msg)) = self.logs.first() {
|
||||||
|
Some(
|
||||||
|
MessageBuilder::new()
|
||||||
|
.message(&time.to_string())
|
||||||
|
.append(MessageBuilder::from_message(msg.clone()))
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
if let Some(_) = res {
|
||||||
|
self.logs.remove(0);
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +1,23 @@
|
||||||
use std::panic;
|
use crate::message;
|
||||||
|
|
||||||
use crate::kernel::tty::tty::{Color, MessageBuilder, 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 ttyptr = unsafe { tty.get_c_tty_t() };
|
tty.enable();
|
||||||
|
let mut logger = KernelLogger::new();
|
||||||
let hello = MessageBuilder::new()
|
logger.info(message!(
|
||||||
.message("Hello, ".to_string())
|
Msg("Hello, "),
|
||||||
.message("Metaverse".to_string())
|
Msg("Metaverse"),
|
||||||
.foreground_color(Color(0xa, 0xee, 0xa))
|
FgColor(Color::GREEN),
|
||||||
.message("!\n".to_string())
|
Msg("!\n")
|
||||||
.build();
|
));
|
||||||
tty.print(hello);
|
for msg in logger.iter(LoggerLevel::Info) {
|
||||||
|
tty.print(msg);
|
||||||
|
}
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,17 +17,19 @@ void *raw_allocator_allocate(raw_allocator_t *allocator, usize size, usize align
|
||||||
{
|
{
|
||||||
usize real_size = size;
|
usize real_size = size;
|
||||||
align_to(real_size, 16);
|
align_to(real_size, 16);
|
||||||
raw_allocator_cell *cell = allocator->cells;
|
raw_allocator_cell *cell = &allocator->cells;
|
||||||
while ((void *)raw_allocator_next_cell(cell) < (void *)allocator + allocator->size)
|
while ((void *)cell < raw_allocator_end(allocator))
|
||||||
{
|
{
|
||||||
while ( // 确保cell指向的内容还在这个allocator内
|
while ( // 确保cell指向的内容还在这个allocator内
|
||||||
(void *)raw_allocator_next_cell(cell) < raw_allocator_end(allocator) &&
|
(void *)cell < raw_allocator_end(allocator) &&
|
||||||
cell->length != 0)
|
cell->length != 0)
|
||||||
{
|
{
|
||||||
cell = raw_allocator_next_cell(cell);
|
cell = raw_allocator_next_cell(cell);
|
||||||
}
|
}
|
||||||
if (real_size <= cell->capacity)
|
if (real_size <= cell->capacity)
|
||||||
break;
|
break;
|
||||||
|
else
|
||||||
|
cell = raw_allocator_next_cell(cell);
|
||||||
}
|
}
|
||||||
if ((void *)cell < raw_allocator_end(allocator))
|
if ((void *)cell < raw_allocator_end(allocator))
|
||||||
goto fitable_cell_finded;
|
goto fitable_cell_finded;
|
||||||
|
|
|
@ -192,7 +192,7 @@ void *memm_allocate(usize size, usize pid)
|
||||||
MEMM_RAW_ALLOCATOR, pid);
|
MEMM_RAW_ALLOCATOR, pid);
|
||||||
allocator = new_allocator;
|
allocator = new_allocator;
|
||||||
|
|
||||||
allocator_iterator_t *allind = memm_allocate(sizeof(allocator_iterator_t), 0);
|
allocator_iterator_t *allind = memm_kernel_allocate(sizeof(allocator_iterator_t));
|
||||||
allind->allocator = new_allocator;
|
allind->allocator = new_allocator;
|
||||||
allind->left = nullptr;
|
allind->left = nullptr;
|
||||||
allind->right = nullptr;
|
allind->right = nullptr;
|
||||||
|
@ -200,15 +200,23 @@ void *memm_allocate(usize size, usize pid)
|
||||||
ptr = new_allocator->allocate(&new_allocator->allocator_instance, orgsize, 0);
|
ptr = new_allocator->allocate(&new_allocator->allocator_instance, orgsize, 0);
|
||||||
|
|
||||||
after_allocation:
|
after_allocation:
|
||||||
|
if (ptr != nullptr)
|
||||||
memm_addr_set_allocator(ptr, allocator);
|
memm_addr_set_allocator(ptr, allocator);
|
||||||
if (pid != 0)
|
|
||||||
{ // TODO 进程管理中应该有一个用户地址-内核地址映射表
|
|
||||||
// 在进程分配时将页映射到用户空间中,并将这个映射关系记录进这个表中
|
|
||||||
// 需要返回的是用户空间的地址
|
|
||||||
}
|
|
||||||
return ptr;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
void memm_free(void *mem)
|
void memm_free(void *mem)
|
||||||
{
|
{
|
||||||
allocator_t *allocator = memm_addr_get_allocator(mem);
|
allocator_t *allocator = memm_addr_get_allocator(mem);
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
extern crate core;
|
extern crate core;
|
||||||
|
|
||||||
use core::alloc::{GlobalAlloc, Layout};
|
use core::{
|
||||||
|
alloc::{GlobalAlloc, Layout},
|
||||||
|
ptr::null_mut,
|
||||||
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn memm_allocate(size: usize, pid: usize) -> *mut u8;
|
pub fn memm_kernel_allocate(size: usize) -> *mut u8;
|
||||||
|
// pub fn memm_user_allocate(size: usize, pid: usize);
|
||||||
pub fn memm_free(mem: *mut u8);
|
pub fn memm_free(mem: *mut u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +15,14 @@ pub struct KernelAllocator {}
|
||||||
|
|
||||||
unsafe impl GlobalAlloc for KernelAllocator {
|
unsafe impl GlobalAlloc for KernelAllocator {
|
||||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||||
memm_allocate(layout.size(), 0)
|
let res = memm_kernel_allocate(layout.size());
|
||||||
|
if res == null_mut() {
|
||||||
|
panic!(
|
||||||
|
"Kernel allocator failed to allocate {} byte(s) memory.",
|
||||||
|
layout.size()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
|
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
pub mod clock;
|
||||||
|
pub mod klog;
|
||||||
|
pub mod main;
|
||||||
pub mod memm;
|
pub mod memm;
|
||||||
pub mod tty;
|
pub mod tty;
|
||||||
pub mod main;
|
pub mod sync;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod rwlock;
|
|
@ -0,0 +1,129 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -405,7 +405,7 @@ u64 font[256][64] = {
|
||||||
0b00000000,
|
0b00000000,
|
||||||
0b00011000, ///
|
0b00011000, ///
|
||||||
0b00101000,
|
0b00101000,
|
||||||
0b01001000,
|
0b00001000,
|
||||||
0b00001000,
|
0b00001000,
|
||||||
0b00001000,
|
0b00001000,
|
||||||
0b00001000,
|
0b00001000,
|
||||||
|
|
|
@ -1 +1,46 @@
|
||||||
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_rules! message {
|
||||||
|
( $( $e : expr ),* ) => {{
|
||||||
|
use crate::{
|
||||||
|
kernel::tty::tty::{MessageBuilder, BuilderFunctions},
|
||||||
|
message_msg, message_fgc, message_bgc
|
||||||
|
};
|
||||||
|
let mut tmp_builder = MessageBuilder::new();
|
||||||
|
$(
|
||||||
|
if let BuilderFunctions::Msg(e) = $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()
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
|
@ -11,26 +11,29 @@ tty_controller_t *tty_controller_new()
|
||||||
{
|
{
|
||||||
memset(tty_ctrler.ttys, 0, sizeof(tty_ctrler.ttys));
|
memset(tty_ctrler.ttys, 0, sizeof(tty_ctrler.ttys));
|
||||||
memset(tty_ctrler.map, 0, sizeof(tty_ctrler.map));
|
memset(tty_ctrler.map, 0, sizeof(tty_ctrler.map));
|
||||||
|
memset(tty_ctrler.enabled, 0, sizeof(tty_ctrler.enabled));
|
||||||
return &tty_ctrler;
|
return &tty_ctrler;
|
||||||
}
|
}
|
||||||
|
|
||||||
tty *tty_new(tty_type type, tty_mode mode)
|
tty *tty_new(tty_type type, tty_mode mode)
|
||||||
{
|
{
|
||||||
tty *__tty = memm_allocate(sizeof(tty), 0);
|
|
||||||
memset(__tty, 0, sizeof(tty));
|
|
||||||
__tty->type = type;
|
|
||||||
__tty->mode = mode;
|
|
||||||
tty *res = nullptr;
|
tty *res = nullptr;
|
||||||
for (usize i = 0; i < TTY_MAX_NUM; ++i)
|
for (usize i = 0; i < TTY_MAX_NUM; ++i)
|
||||||
{
|
{
|
||||||
if (tty_ctrler.map[i] == false)
|
if (tty_ctrler.map[i] == false)
|
||||||
{
|
{
|
||||||
res = __tty;
|
res = memm_kernel_allocate(sizeof(tty));
|
||||||
__tty->id = i;
|
res->id = i;
|
||||||
tty_ctrler.ttys[i] = __tty;
|
tty_ctrler.ttys[i] = res;
|
||||||
tty_ctrler.map[i] = true;
|
tty_ctrler.map[i] = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
res->type = type;
|
||||||
|
res->mode = mode;
|
||||||
|
res->enabled = false;
|
||||||
|
res->width = 0;
|
||||||
|
res->height = 0;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,10 +54,14 @@ void tty_set_framebuffer(tty *ttyx, framebuffer *fb)
|
||||||
if (ttyx->type != tty_type_raw_framebuffer)
|
if (ttyx->type != tty_type_raw_framebuffer)
|
||||||
return;
|
return;
|
||||||
memcpy(&ttyx->typeinfo.raw_framebuffer, fb, sizeof(framebuffer));
|
memcpy(&ttyx->typeinfo.raw_framebuffer, fb, sizeof(framebuffer));
|
||||||
|
ttyx->width = ttyx->typeinfo.raw_framebuffer.width;
|
||||||
|
ttyx->height = ttyx->typeinfo.raw_framebuffer.height;
|
||||||
if (ttyx->mode == tty_mode_text)
|
if (ttyx->mode == tty_mode_text)
|
||||||
{
|
{
|
||||||
ttyx->text.width = fb->width / tty_get_font()->char_width;
|
ttyx->text.width = fb->width / tty_get_font()->char_width;
|
||||||
ttyx->text.height = fb->height / tty_get_font()->char_height;
|
ttyx->text.height = fb->height / tty_get_font()->char_height;
|
||||||
|
ttyx->text.line = 0;
|
||||||
|
ttyx->text.column = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +94,8 @@ inline static void putchar(
|
||||||
{
|
{
|
||||||
for (usize b = 0; b < TTY_FONT_SCALE; ++b)
|
for (usize b = 0; b < TTY_FONT_SCALE; ++b)
|
||||||
{
|
{
|
||||||
put_pixel(ttyx->typeinfo.raw_framebuffer.pointer,
|
put_pixel(
|
||||||
|
ttyx->typeinfo.raw_framebuffer.pointer,
|
||||||
ttyx->typeinfo.raw_framebuffer.width,
|
ttyx->typeinfo.raw_framebuffer.width,
|
||||||
ttyx->typeinfo.raw_framebuffer.pixsize,
|
ttyx->typeinfo.raw_framebuffer.pixsize,
|
||||||
ttyx->text.column * font->char_width * TTY_FONT_SCALE + i * TTY_FONT_SCALE + a,
|
ttyx->text.column * font->char_width * TTY_FONT_SCALE + i * TTY_FONT_SCALE + a,
|
||||||
|
@ -102,7 +110,8 @@ inline static void putchar(
|
||||||
{
|
{
|
||||||
for (usize b = 0; b < TTY_FONT_SCALE; ++b)
|
for (usize b = 0; b < TTY_FONT_SCALE; ++b)
|
||||||
{
|
{
|
||||||
put_pixel(ttyx->typeinfo.raw_framebuffer.pointer,
|
put_pixel(
|
||||||
|
ttyx->typeinfo.raw_framebuffer.pointer,
|
||||||
ttyx->typeinfo.raw_framebuffer.width,
|
ttyx->typeinfo.raw_framebuffer.width,
|
||||||
ttyx->typeinfo.raw_framebuffer.pixsize,
|
ttyx->typeinfo.raw_framebuffer.pixsize,
|
||||||
ttyx->text.column * font->char_width * TTY_FONT_SCALE + i * TTY_FONT_SCALE + a,
|
ttyx->text.column * font->char_width * TTY_FONT_SCALE + i * TTY_FONT_SCALE + a,
|
||||||
|
@ -121,7 +130,8 @@ inline static void newline(tty *ttyx)
|
||||||
ttyx->text.line++;
|
ttyx->text.line++;
|
||||||
if (ttyx->text.line == ttyx->text.height)
|
if (ttyx->text.line == ttyx->text.height)
|
||||||
{
|
{
|
||||||
scroll_buffer(ttyx->typeinfo.raw_framebuffer.pointer,
|
scroll_buffer(
|
||||||
|
ttyx->typeinfo.raw_framebuffer.pointer,
|
||||||
ttyx->typeinfo.raw_framebuffer.width,
|
ttyx->typeinfo.raw_framebuffer.width,
|
||||||
ttyx->typeinfo.raw_framebuffer.height,
|
ttyx->typeinfo.raw_framebuffer.height,
|
||||||
ttyx->typeinfo.raw_framebuffer.pixsize,
|
ttyx->typeinfo.raw_framebuffer.pixsize,
|
||||||
|
@ -132,6 +142,11 @@ inline static void newline(tty *ttyx)
|
||||||
|
|
||||||
void tty_text_print(tty *ttyx, char *string, u32 color, u32 bgcolor)
|
void tty_text_print(tty *ttyx, char *string, u32 color, u32 bgcolor)
|
||||||
{
|
{
|
||||||
|
if (ttyx->enabled == false)
|
||||||
|
return;
|
||||||
|
// TODO 暂时只支持framebuffer
|
||||||
|
if (ttyx->type != tty_type_raw_framebuffer)
|
||||||
|
return;
|
||||||
if (ttyx->mode != tty_mode_text)
|
if (ttyx->mode != tty_mode_text)
|
||||||
return;
|
return;
|
||||||
if (ttyx->typeinfo.raw_framebuffer.pixtype == bgr)
|
if (ttyx->typeinfo.raw_framebuffer.pixtype == bgr)
|
||||||
|
@ -147,13 +162,14 @@ void tty_text_print(tty *ttyx, char *string, u32 color, u32 bgcolor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tty_font_t *font = tty_get_font();
|
tty_font_t *font = tty_get_font();
|
||||||
simple_lock_lock(ttyx->text.lock);
|
|
||||||
usize len = strlen(string);
|
usize len = strlen(string);
|
||||||
|
simple_lock_lock(ttyx->text.lock);
|
||||||
for (char *str = string; string - str < len; string++)
|
for (char *str = string; string - str < len; string++)
|
||||||
{
|
{
|
||||||
char c = *string;
|
char c = *string;
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
{ // 换行
|
{ // 换行
|
||||||
|
putchar(ttyx, ' ', 0, 0);
|
||||||
newline(ttyx);
|
newline(ttyx);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -173,7 +189,8 @@ void tty_text_print(tty *ttyx, char *string, u32 color, u32 bgcolor)
|
||||||
ttyx->text.line++;
|
ttyx->text.line++;
|
||||||
if (ttyx->text.line == ttyx->text.height)
|
if (ttyx->text.line == ttyx->text.height)
|
||||||
{
|
{
|
||||||
scroll_buffer(ttyx->typeinfo.raw_framebuffer.pointer,
|
scroll_buffer(
|
||||||
|
ttyx->typeinfo.raw_framebuffer.pointer,
|
||||||
ttyx->typeinfo.raw_framebuffer.width,
|
ttyx->typeinfo.raw_framebuffer.width,
|
||||||
ttyx->typeinfo.raw_framebuffer.height,
|
ttyx->typeinfo.raw_framebuffer.height,
|
||||||
ttyx->typeinfo.raw_framebuffer.pixsize,
|
ttyx->typeinfo.raw_framebuffer.pixsize,
|
||||||
|
@ -192,7 +209,8 @@ void tty_text_print(tty *ttyx, char *string, u32 color, u32 bgcolor)
|
||||||
}
|
}
|
||||||
else if (c == '\f')
|
else if (c == '\f')
|
||||||
{ // 滚动一行
|
{ // 滚动一行
|
||||||
scroll_buffer(ttyx->typeinfo.raw_framebuffer.pointer,
|
scroll_buffer(
|
||||||
|
ttyx->typeinfo.raw_framebuffer.pointer,
|
||||||
ttyx->typeinfo.raw_framebuffer.width,
|
ttyx->typeinfo.raw_framebuffer.width,
|
||||||
ttyx->typeinfo.raw_framebuffer.height,
|
ttyx->typeinfo.raw_framebuffer.height,
|
||||||
ttyx->typeinfo.raw_framebuffer.pixsize,
|
ttyx->typeinfo.raw_framebuffer.pixsize,
|
||||||
|
@ -213,3 +231,58 @@ void tty_text_print(tty *ttyx, char *string, u32 color, u32 bgcolor)
|
||||||
putchar(ttyx, '\0', gen_color(0x88, 0x88, 0x88), 0);
|
putchar(ttyx, '\0', gen_color(0x88, 0x88, 0x88), 0);
|
||||||
simple_lock_unlock(ttyx->text.lock);
|
simple_lock_unlock(ttyx->text.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
usize tty_get_width(tty *ttyx)
|
||||||
|
{
|
||||||
|
if (ttyx->mode == tty_mode_text)
|
||||||
|
return ttyx->text.width;
|
||||||
|
return ttyx->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
usize tty_get_height(tty *ttyx)
|
||||||
|
{
|
||||||
|
if (ttyx->mode == tty_mode_text)
|
||||||
|
return ttyx->text.height;
|
||||||
|
return ttyx->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
tty_type tty_get_type(tty *ttyx)
|
||||||
|
{
|
||||||
|
return ttyx->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
tty_mode tty_get_mode(tty *ttyx)
|
||||||
|
{
|
||||||
|
return ttyx->mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tty_is_enabled(tty *ttyx)
|
||||||
|
{
|
||||||
|
return ttyx->enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tty_enable(tty *ttyx)
|
||||||
|
{
|
||||||
|
if (tty_ctrler.enabled[ttyx->id])
|
||||||
|
return false;
|
||||||
|
if (ttyx->type == tty_type_raw_framebuffer)
|
||||||
|
{
|
||||||
|
for (usize i = 0; i < TTY_MAX_NUM; ++i)
|
||||||
|
{
|
||||||
|
if (ttyx->id != i &&
|
||||||
|
tty_ctrler.enabled[i] != nullptr &&
|
||||||
|
tty_ctrler.ttys[i]->type == tty_type_raw_framebuffer)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ttyx->enabled = true;
|
||||||
|
tty_ctrler.enabled[ttyx->id] = ttyx;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tty_disable(tty *ttyx)
|
||||||
|
{
|
||||||
|
ttyx->enabled = false;
|
||||||
|
tty_ctrler.enabled[ttyx->id] = false;
|
||||||
|
}
|
||||||
|
|
|
@ -1,25 +1,61 @@
|
||||||
use std::{
|
use core::ptr::null_mut;
|
||||||
io::{BufWriter, Write},
|
|
||||||
ptr::null_mut,
|
use alloc::{
|
||||||
|
string::{String, ToString},
|
||||||
|
vec,
|
||||||
|
vec::Vec,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn tty_new(tty_type: u8, mode: u8) -> *mut u8;
|
pub fn tty_new(tty_type: u8, mode: u8) -> *mut u8;
|
||||||
fn tty_get(id: usize) -> *mut *mut u8;
|
pub fn tty_get(id: usize) -> *mut *mut u8;
|
||||||
pub fn tty_text_print(ttyx: *mut u8, string: *mut u8, color: u32, bgcolor: u32);
|
pub fn tty_text_print(ttyx: *mut u8, string: *mut u8, color: u32, bgcolor: u32);
|
||||||
fn tty_get_id(tty: *mut u8) -> usize;
|
pub fn tty_get_id(tty: *mut u8) -> usize;
|
||||||
|
|
||||||
|
pub fn tty_get_width(tty: *mut u8) -> usize;
|
||||||
|
pub fn tty_get_height(tty: *mut u8) -> usize;
|
||||||
|
|
||||||
|
pub fn tty_get_type(tty: *mut u8) -> u8;
|
||||||
|
pub fn tty_get_mode(tty: *mut u8) -> u8;
|
||||||
|
|
||||||
|
pub fn tty_is_enabled(tty: *mut u8) -> bool;
|
||||||
|
|
||||||
|
pub fn tty_enable(tty: *mut u8) -> bool;
|
||||||
|
pub fn tty_disable(tty: *mut u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
Invalid = 0,
|
Invalid = 0,
|
||||||
RawFramebuffer = 1,
|
RawFramebuffer = 1,
|
||||||
Display = 2,
|
Display = 2,
|
||||||
VirtualTty = 3,
|
VirtualTerm = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for Type {
|
||||||
|
fn from(value: u8) -> Self {
|
||||||
|
match value {
|
||||||
|
1 => Type::RawFramebuffer,
|
||||||
|
2 => Type::Display,
|
||||||
|
3 => Type::VirtualTerm,
|
||||||
|
_ => Type::Invalid,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
Text = 0,
|
Invalid = 0,
|
||||||
Graphics = 1,
|
Text = 1,
|
||||||
|
Graphics = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for Mode {
|
||||||
|
fn from(value: u8) -> Self {
|
||||||
|
match value {
|
||||||
|
1 => Mode::Text,
|
||||||
|
2 => Mode::Graphics,
|
||||||
|
_ => Mode::Invalid,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Tty {
|
pub struct Tty {
|
||||||
|
@ -50,12 +86,43 @@ impl Tty {
|
||||||
unsafe { tty_get_id(self.tty_pointer) }
|
unsafe { tty_get_id(self.tty_pointer) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn size(&self) -> Resolution {
|
||||||
|
unsafe {
|
||||||
|
Resolution {
|
||||||
|
width: tty_get_width(self.tty_pointer),
|
||||||
|
height: tty_get_height(self.tty_pointer),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_type(&self) -> Type {
|
||||||
|
let tp = unsafe { tty_get_type(self.tty_pointer) };
|
||||||
|
Type::from(tp)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mode(&self) -> Mode {
|
||||||
|
let mode = unsafe { tty_get_mode(self.tty_pointer) };
|
||||||
|
Mode::from(mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_enabled(&self) -> bool {
|
||||||
|
unsafe { tty_is_enabled(self.tty_pointer) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn enable(&self) {
|
||||||
|
unsafe { tty_enable(self.tty_pointer) };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn disable(&self) {
|
||||||
|
unsafe { tty_disable(self.tty_pointer) };
|
||||||
|
}
|
||||||
|
|
||||||
pub fn print(&self, msg: Message) {
|
pub fn print(&self, msg: Message) {
|
||||||
for MessageSection {
|
for MessageSection {
|
||||||
mut msg,
|
mut msg,
|
||||||
fgcolor,
|
fgcolor,
|
||||||
bgcolor,
|
bgcolor,
|
||||||
} in msg.into_iter()
|
} in msg.0.into_iter()
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let string = msg.as_bytes_mut() as *mut [u8] as *mut u8;
|
let string = msg.as_bytes_mut() as *mut [u8] as *mut u8;
|
||||||
|
@ -74,8 +141,21 @@ impl Tty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct Color(pub u8, pub u8, pub u8);
|
pub struct Color(pub u8, pub u8, pub u8);
|
||||||
|
|
||||||
|
impl Color {
|
||||||
|
pub const WHITE: Color = Color(0xee, 0xee, 0xee);
|
||||||
|
pub const BLACK: Color = Color(0, 0, 0);
|
||||||
|
pub const RED: Color = Color(0xee, 0x22, 0x22);
|
||||||
|
pub const GREEN: Color = Color(0x22, 0xee, 0x22);
|
||||||
|
pub const BLUE: Color = Color(0x22, 0x22, 0xee);
|
||||||
|
pub const YELLOW: Color = Color(0xee, 0x22, 0x22);
|
||||||
|
pub const ORANGE: Color = Color(0xee, 0xee, 0x22);
|
||||||
|
pub const PURPLE: Color = Color(0xee, 0, 0xee);
|
||||||
|
pub const PINK: Color = Color(0xee, 0x44, 0x66);
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Color> for u32 {
|
impl From<Color> for u32 {
|
||||||
fn from(value: Color) -> Self {
|
fn from(value: Color) -> Self {
|
||||||
let res = (value.0 as u32) << 16 | (value.1 as u32) << 8 | (value.2 as u32);
|
let res = (value.0 as u32) << 16 | (value.1 as u32) << 8 | (value.2 as u32);
|
||||||
|
@ -83,46 +163,117 @@ impl From<Color> for u32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Resolution {
|
||||||
|
pub width: usize,
|
||||||
|
pub height: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct MessageSection {
|
pub struct MessageSection {
|
||||||
msg: String,
|
msg: String,
|
||||||
fgcolor: Color,
|
fgcolor: Color,
|
||||||
bgcolor: Color,
|
bgcolor: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Message = Vec<MessageSection>;
|
/// ## Message
|
||||||
|
///
|
||||||
|
/// 用`MessageBuilder`构造一个`Message`对象
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Message(Vec<MessageSection>);
|
||||||
|
|
||||||
|
/// ## MessageBuilder
|
||||||
|
///
|
||||||
|
/// 使用链式调用模式构造一个消息.
|
||||||
|
///
|
||||||
|
/// 一个`Message`包含多个`MessageSection`,每个`MessageSection`以`message()`调用开始,
|
||||||
|
/// `message()`调用后可接0个或多个属性设置。
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// MessageBuilder::new()
|
||||||
|
/// .message("Hello, ")
|
||||||
|
/// .message("Metaverse").foreground_color(Color(0xa, 0xee, 0xa))
|
||||||
|
/// .message("!\n")
|
||||||
|
/// .build();
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// 对于特殊情况可以使用非链式调用:
|
||||||
|
/// ```rust
|
||||||
|
/// let mut msg = MessageBuilder::new();
|
||||||
|
/// msg.message_mut("Hello, ");
|
||||||
|
/// msg.message_mut("Metaverse");
|
||||||
|
/// msg.foreground_color(Color(0xa, 0xee, 0xa));
|
||||||
|
/// msg.message_mut("!\n");
|
||||||
|
/// let msg = msg.build();
|
||||||
|
/// ```
|
||||||
pub struct MessageBuilder {
|
pub struct MessageBuilder {
|
||||||
msg: Message,
|
msg: Message,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum BuilderFunctions<'a> {
|
||||||
|
Msg(&'a str),
|
||||||
|
FgColor(Color),
|
||||||
|
BgColor(Color),
|
||||||
|
}
|
||||||
|
|
||||||
impl MessageBuilder {
|
impl MessageBuilder {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self { msg: vec![] }
|
Self {
|
||||||
|
msg: Message(vec![]),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn message(mut self, msg: String) -> Self {
|
pub fn from_message(msg: Message) -> Self {
|
||||||
self.msg.push(MessageSection {
|
Self { msg }
|
||||||
msg,
|
}
|
||||||
|
|
||||||
|
pub fn message(mut self, msg: &str) -> Self {
|
||||||
|
self.msg.0.push(MessageSection {
|
||||||
|
msg: msg.to_string(),
|
||||||
fgcolor: Color(0xee, 0xee, 0xee),
|
fgcolor: Color(0xee, 0xee, 0xee),
|
||||||
bgcolor: Color(0, 0, 0),
|
bgcolor: Color(0, 0, 0),
|
||||||
});
|
});
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn message_mut(&mut self, msg: &str) {
|
||||||
|
self.msg.0.push(MessageSection {
|
||||||
|
msg: msg.to_string(),
|
||||||
|
fgcolor: Color(0xee, 0xee, 0xee),
|
||||||
|
bgcolor: Color(0, 0, 0),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn background_color(mut self, color: Color) -> Self {
|
pub fn background_color(mut self, color: Color) -> Self {
|
||||||
if let Some(msg) = self.msg.last_mut() {
|
if let Some(msg) = self.msg.0.last_mut() {
|
||||||
msg.bgcolor = color;
|
msg.bgcolor = color;
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn background_color_mut(&mut self, color: Color) {
|
||||||
|
if let Some(msg) = self.msg.0.last_mut() {
|
||||||
|
msg.bgcolor = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn foreground_color(mut self, color: Color) -> Self {
|
pub fn foreground_color(mut self, color: Color) -> Self {
|
||||||
if let Some(msg) = self.msg.last_mut() {
|
if let Some(msg) = self.msg.0.last_mut() {
|
||||||
msg.fgcolor = color;
|
msg.fgcolor = color;
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn foreground_color_mut(&mut self, color: Color) {
|
||||||
|
if let Some(msg) = self.msg.0.last_mut() {
|
||||||
|
msg.fgcolor = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn append(mut self, mut builder: Self) -> Self {
|
||||||
|
self.msg.0.append(&mut builder.msg.0);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn build(self) -> Message {
|
pub fn build(self) -> Message {
|
||||||
self.msg
|
self.msg
|
||||||
}
|
}
|
||||||
|
|
67
src/lib.rs
67
src/lib.rs
|
@ -1,4 +1,69 @@
|
||||||
extern crate core;
|
#![no_std]
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
|
use alloc::{
|
||||||
|
string::{String, ToString},
|
||||||
|
vec::Vec,
|
||||||
|
};
|
||||||
|
use core::{panic::PanicInfo, ptr::null_mut};
|
||||||
|
|
||||||
|
use kernel::tty::tty::{self, tty_enable, tty_text_print, Color};
|
||||||
|
|
||||||
pub mod kernel;
|
pub mod kernel;
|
||||||
pub mod libk;
|
pub mod libk;
|
||||||
|
|
||||||
|
#[panic_handler]
|
||||||
|
unsafe fn kernel_panic_handler(info: &PanicInfo) -> ! {
|
||||||
|
let line_in_file = if let Some(loca) = info.location() {
|
||||||
|
loca.line().to_string()
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
};
|
||||||
|
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 {}
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
lst_iterator_t *lst_new(usize start, usize end)
|
lst_iterator_t *lst_new(usize start, usize end)
|
||||||
{
|
{
|
||||||
lst_iterator_t *lst = memm_allocate(sizeof(lst_iterator_t), 0);
|
lst_iterator_t *lst = memm_kernel_allocate(sizeof(lst_iterator_t));
|
||||||
lst->line.left = start;
|
lst->line.left = start;
|
||||||
lst->line.right = end;
|
lst->line.right = end;
|
||||||
lst->next = nullptr;
|
lst->next = nullptr;
|
||||||
|
@ -128,7 +128,7 @@ bool lst_add(lst_iterator_t *lst, usize left, usize right, bool force)
|
||||||
lst->line.left = left;
|
lst->line.left = left;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lst_iterator_t *new_node = memm_allocate(sizeof(lst_iterator_t), 0);
|
lst_iterator_t *new_node = memm_kernel_allocate(sizeof(lst_iterator_t));
|
||||||
new_node->line = line;
|
new_node->line = line;
|
||||||
new_node->next = lst;
|
new_node->next = lst;
|
||||||
if (last != nullptr)
|
if (last != nullptr)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod string;
|
|
@ -17,12 +17,6 @@ SECTIONS {
|
||||||
{
|
{
|
||||||
*(.cpumeta)
|
*(.cpumeta)
|
||||||
}
|
}
|
||||||
. = 4M;
|
|
||||||
..kstack :
|
|
||||||
{
|
|
||||||
kstack = .;
|
|
||||||
*(.kstack)
|
|
||||||
}
|
|
||||||
. = 16M;
|
. = 16M;
|
||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
|
@ -62,6 +56,50 @@ SECTIONS {
|
||||||
{}
|
{}
|
||||||
.igot.plt :
|
.igot.plt :
|
||||||
{}
|
{}
|
||||||
|
.tbss :
|
||||||
|
{
|
||||||
|
*(.tbss)
|
||||||
|
}
|
||||||
|
.tdata :
|
||||||
|
{
|
||||||
|
*(.tdata)
|
||||||
|
}
|
||||||
|
.debug_line :
|
||||||
|
{
|
||||||
|
*(.debug_line)
|
||||||
|
}
|
||||||
|
.debug_abbrev :
|
||||||
|
{
|
||||||
|
*(.debug_abbrev)
|
||||||
|
}
|
||||||
|
.debug_info :
|
||||||
|
{
|
||||||
|
*(.debug_info)
|
||||||
|
}
|
||||||
|
.debug_str :
|
||||||
|
{
|
||||||
|
*(.debug_str)
|
||||||
|
}
|
||||||
|
.debug_aranges :
|
||||||
|
{
|
||||||
|
*(.debug_aranges)
|
||||||
|
}
|
||||||
|
.debug_ranges :
|
||||||
|
{
|
||||||
|
*(.debug_ranges)
|
||||||
|
}
|
||||||
|
.debug_pubnames :
|
||||||
|
{
|
||||||
|
*(.debug_pubnames)
|
||||||
|
}
|
||||||
|
.debug_pubtypes :
|
||||||
|
{
|
||||||
|
*(.debug_pubtypes)
|
||||||
|
}
|
||||||
|
.debug_frame :
|
||||||
|
{
|
||||||
|
*(.debug_frame)
|
||||||
|
}
|
||||||
.kend :
|
.kend :
|
||||||
{
|
{
|
||||||
*(.kend)
|
*(.kend)
|
||||||
|
|
Reference in New Issue