增加内核日志

This commit is contained in:
pointer-to-bios 2024-02-01 01:40:51 +08:00
parent 85df2a7609
commit d931f612f8
10 changed files with 233 additions and 169 deletions

View File

@ -46,7 +46,6 @@ metaverse.elf: kernel libk rust metaverse.lds
@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:=yellow" "error:=red" "ld=lyellow"
@strip $@
.PHONY: kernel libk all clear postproc rust .PHONY: kernel libk all clear postproc rust

View File

@ -1,6 +1,8 @@
use core::{cmp::Ordering, ops::Sub, time::Duration}; use core::{cmp::Ordering, ops::Sub, time::Duration};
use alloc::{format, string::ToString}; use alloc::string::ToString;
use crate::format;
extern "C" { extern "C" {
fn system_time_get() -> usize; fn system_time_get() -> usize;
@ -96,7 +98,7 @@ impl ToString for SystemTime {
let milisec = second % second_dur; let milisec = second % second_dur;
second /= second_dur; second /= second_dur;
format!( format!(
"[{:02}-{:02}-{:02} {:02}:{:02}:{:02}.{:03}]", "[ {}-{}-{} {}:{}:{}.{} ]",
year, month, day, hour, minute, second, milisec year, month, day, hour, minute, second, milisec
) )
} }

View File

@ -1,6 +1,6 @@
use alloc::string::ToString; use alloc::string::ToString;
use alloc::{format, vec::Vec};
use alloc::vec; use alloc::vec;
use alloc::vec::Vec;
use super::{ use super::{
clock::time::SystemTime, clock::time::SystemTime,
@ -40,125 +40,157 @@ impl KernelLogger {
pub fn fatal(&mut self, msg: Message) { pub fn fatal(&mut self, msg: Message) {
let msg = MessageBuilder::new() let msg = MessageBuilder::new()
.message("Fatal: ".to_string()) .message("Fatal: ")
.foreground_color(Color(0xee, 0xa, 0xa)) .foreground_color(Color(0xee, 0xa, 0xa))
.append(MessageBuilder::from_message(&msg)) .append(MessageBuilder::from_message(msg))
.build(); .build();
self.fatal_queue.push((SystemTime::now(), msg)); self.fatal_queue.push((SystemTime::now(), msg));
} }
pub fn error(&mut self, msg: Message) { pub fn error(&mut self, msg: Message) {
let msg = MessageBuilder::new() let msg = MessageBuilder::new()
.message("Error: ".to_string()) .message("Error: ")
.foreground_color(Color(0xaa, 0x22, 0x22)) .foreground_color(Color(0xaa, 0x22, 0x22))
.append(MessageBuilder::from_message(&msg)) .append(MessageBuilder::from_message(msg))
.build(); .build();
self.error_queue.push((SystemTime::now(), msg)); self.error_queue.push((SystemTime::now(), msg));
} }
pub fn warning(&mut self, msg: Message) { pub fn warning(&mut self, msg: Message) {
let msg = MessageBuilder::new() let msg = MessageBuilder::new()
.message("Warning: ".to_string()) .message("Warning: ")
.foreground_color(Color(0xaa, 0xa, 0xaa)) .foreground_color(Color(0xaa, 0xa, 0xaa))
.append(MessageBuilder::from_message(&msg)) .append(MessageBuilder::from_message(msg))
.build(); .build();
self.warning_queue.push((SystemTime::now(), msg)); self.warning_queue.push((SystemTime::now(), msg));
} }
pub fn info(&mut self, msg: Message) { pub fn info(&mut self, msg: Message) {
let msg = MessageBuilder::new() let msg = MessageBuilder::new()
.message("Info: ".to_string()) .message("Info: ")
.foreground_color(Color(0xa, 0xee, 0xa)) .foreground_color(Color(0xa, 0xee, 0xa))
.append(MessageBuilder::from_message(&msg)) .append(MessageBuilder::from_message(msg))
.build(); .build();
self.info_queue.push((SystemTime::now(), msg)); self.info_queue.push((SystemTime::now(), msg));
} }
pub fn debug(&mut self, msg: Message) { pub fn debug(&mut self, msg: Message) {
let msg = MessageBuilder::new() let msg = MessageBuilder::new()
.message("Debug: ".to_string()) .message("Debug: ")
.foreground_color(Color(0xee, 0xee, 0xee)) .foreground_color(Color(0xee, 0xee, 0xee))
.append(MessageBuilder::from_message(&msg)) .append(MessageBuilder::from_message(msg))
.build(); .build();
self.debug_queue.push((SystemTime::now(), msg)); self.debug_queue.push((SystemTime::now(), msg));
} }
pub fn trace(&mut self, msg: Message) { pub fn trace(&mut self, msg: Message) {
let msg = MessageBuilder::new() let msg = MessageBuilder::new()
.message("Trace: ".to_string()) .message("Trace: ")
.foreground_color(Color(0xee, 0xee, 0xee)) .foreground_color(Color(0xee, 0xee, 0xee))
.append(MessageBuilder::from_message(&msg)) .append(MessageBuilder::from_message(msg))
.build(); .build();
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![]; let mut logs = vec![];
if level == LoggerLevel::Fatal { match level {
logs.push(&self.fatal_queue); LoggerLevel::Fatal => {
} logs.push(&self.fatal_queue);
if level == LoggerLevel::Fatal || level == LoggerLevel::Error { }
logs.push(&self.error_queue); LoggerLevel::Error => {
} logs.push(&self.fatal_queue);
if level == LoggerLevel::Fatal logs.push(&self.error_queue);
|| level == LoggerLevel::Error }
|| level == LoggerLevel::Warning LoggerLevel::Warning => {
{ logs.push(&self.fatal_queue);
logs.push(&self.warning_queue); logs.push(&self.error_queue);
} logs.push(&self.warning_queue);
if level == LoggerLevel::Fatal }
|| level == LoggerLevel::Error LoggerLevel::Info => {
|| level == LoggerLevel::Warning logs.push(&self.fatal_queue);
|| level == LoggerLevel::Info logs.push(&self.error_queue);
{ logs.push(&self.warning_queue);
logs.push(&self.info_queue); logs.push(&self.info_queue);
} }
if level == LoggerLevel::Fatal LoggerLevel::Debug => {
|| level == LoggerLevel::Error logs.push(&self.fatal_queue);
|| level == LoggerLevel::Warning logs.push(&self.error_queue);
|| level == LoggerLevel::Info logs.push(&self.warning_queue);
|| level == LoggerLevel::Debug logs.push(&self.info_queue);
{ logs.push(&self.debug_queue);
logs.push(&self.debug_queue); }
} LoggerLevel::Trace => {
if level == LoggerLevel::Fatal logs.push(&self.fatal_queue);
|| level == LoggerLevel::Error logs.push(&self.error_queue);
|| level == LoggerLevel::Warning logs.push(&self.warning_queue);
|| level == LoggerLevel::Info logs.push(&self.info_queue);
|| level == LoggerLevel::Debug logs.push(&self.debug_queue);
|| level == LoggerLevel::Trace logs.push(&self.trace_queue);
{ }
logs.push(&self.trace_queue);
} }
let mut res = vec![]; let mut res = vec![];
while let Some(msg) = { let mut indeces = Vec::new();
logs.iter_mut() for _ in 0..logs.len() {
.filter_map(|&mut l| l.first().cloned()) indeces.push(0usize);
.min_by_key(|&(syst, _)| syst) }
} { let all_end = |indeces: &Vec<usize>, logs: &Vec<&Vec<(SystemTime, Message)>>| {
res.push(msg); 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 } LogIterator { logs: res }
} }
} }
pub struct LogIterator { pub struct LogIterator<'a> {
logs: Vec<(SystemTime, Message)>, logs: Vec<&'a (SystemTime, Message)>,
} }
impl Iterator for LogIterator { impl<'a> Iterator for LogIterator<'a> {
type Item = Message; type Item = Message;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
if let Some((time, msg)) = self.logs.first() { let res = if let Some((time, msg)) = self.logs.first() {
Some( Some(
MessageBuilder::new() MessageBuilder::new()
.message(format!("{}", time.to_string())) .message(&time.to_string())
.append(MessageBuilder::from_message(msg)) .append(MessageBuilder::from_message(msg.clone()))
.build(), .build(),
) )
} else { } else {
None None
};
if let Some(_) = res {
self.logs.remove(0);
} }
res
} }
} }

View File

@ -1,17 +1,21 @@
use crate::message;
use super::{ use super::{
klog::{KernelLogger, LoggerLevel}, klog::{KernelLogger, LoggerLevel},
tty::tty::{Color, ColorPair, Message, Tty}, tty::tty::{BuilderFunctions::*, Color, Tty},
}; };
#[no_mangle] #[no_mangle]
extern "C" fn kmain_rust() { extern "C" fn kmain_rust() -> ! {
let mut logger = KernelLogger::new();
logger.info(Message::from(format!(
"Hello, {:?}Metaverse{:?}!",
ColorPair::color(Color(0xa, 0xee, 0xa), Color(0, 0, 0)),
ColorPair::Reset
)));
let tty = Tty::from_id(0).unwrap(); let tty = Tty::from_id(0).unwrap();
tty.enable();
let mut logger = KernelLogger::new();
logger.info(message!(
Msg("Hello, "),
Msg("Metaverse"),
FgColor(Color(0xa, 0xee, 0xa)),
Msg("!\n")
));
for msg in logger.iter(LoggerLevel::Info) { for msg in logger.iter(LoggerLevel::Info) {
tty.print(msg); tty.print(msg);
} }

View File

@ -405,7 +405,7 @@ u64 font[256][64] = {
0b00000000, 0b00000000,
0b00011000, /// 0b00011000, ///
0b00101000, 0b00101000,
0b01001000, 0b00001000,
0b00001000, 0b00001000,
0b00001000, 0b00001000,
0b00001000, 0b00001000,

View File

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

View File

@ -1,7 +1,6 @@
use core::ptr::null_mut; use core::ptr::null_mut;
use alloc::{ use alloc::{
format,
string::{String, ToString}, string::{String, ToString},
vec, vec,
vec::Vec, vec::Vec,
@ -145,38 +144,6 @@ impl Tty {
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Color(pub u8, pub u8, pub u8); pub struct Color(pub u8, pub u8, pub u8);
impl ToString for Color {
fn to_string(&self) -> String {
format!("{:02x}{:02x}{:02x}", self.0, self.1, self.2)
}
}
pub enum ColorPair {
Reset,
Color { fore: Color, back: Color },
}
impl ColorPair {
pub fn reset() -> Self {
ColorPair::Reset
}
pub fn color(fore: Color, back: Color) -> Self {
ColorPair::Color { fore, back }
}
}
impl ToString for ColorPair {
fn to_string(&self) -> String {
match self {
ColorPair::Reset => format!("\x1b{{}}"),
ColorPair::Color { fore, back } => {
format!("\x1b{{{}{}}}", fore.to_string(), back.to_string())
}
}
}
}
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);
@ -196,71 +163,46 @@ pub struct MessageSection {
bgcolor: Color, bgcolor: Color,
} }
/// ## Message
///
/// 用`MessageBuilder`构造一个`Message`对象
#[derive(Clone)] #[derive(Clone)]
pub struct Message(Vec<MessageSection>); pub struct Message(Vec<MessageSection>);
impl From<String> for Message { /// ## MessageBuilder
fn from(value: String) -> Self { ///
let mut res = MessageBuilder::new(); /// 使用链式调用模式构造一个消息.
let mut msg = String::new(); ///
let mut color = ColorPair::Reset; /// 一个`Message`包含多个`MessageSection`,每个`MessageSection`以`message()`调用开始,
let mut coloring = false; /// `message()`调用后可接0个或多个属性设置。
///
let mut colorp_str = String::new(); /// ```rust
/// MessageBuilder::new()
for c in value.as_bytes() { /// .message("Hello, ")
if *c as char == '\x1b' { /// .message("Metaverse").foreground_color(Color(0xa, 0xee, 0xa))
coloring = true; /// .message("!\n")
res.message_mut(msg.clone()); /// .build();
msg.clear(); /// ```
if let ColorPair::Color { fore, back } = color { ///
res.foreground_color_mut(fore); /// 对于特殊情况可以使用非链式调用:
res.background_color_mut(back); /// ```rust
} /// let mut msg = MessageBuilder::new();
continue; /// msg.message_mut("Hello, ");
} /// msg.message_mut("Metaverse");
if coloring { /// msg.foreground_color(Color(0xa, 0xee, 0xa));
if *c as char == '{' { /// msg.message_mut("!\n");
colorp_str.clear(); /// let msg = msg.build();
} else if *c as char == '}' { /// ```
if colorp_str.is_empty() {
color = ColorPair::Reset;
} else {
let bts = colorp_str.as_bytes();
let r = bts[0] << 4 + bts[1];
let g = bts[2] << 4 + bts[3];
let b = bts[4] << 4 + bts[5];
let fore = Color(r, g, b);
let r = bts[6] << 4 + bts[7];
let g = bts[8] << 4 + bts[9];
let b = bts[10] << 4 + bts[11];
let back = Color(r, g, b);
color = ColorPair::Color { fore, back };
}
coloring = false;
} else {
colorp_str.push(*c as char);
}
continue;
}
msg.push(*c as char);
}
if !msg.is_empty() {
res.message_mut(msg.clone());
msg.clear();
if let ColorPair::Color { fore, back } = color {
res.foreground_color_mut(fore);
res.background_color_mut(back);
}
}
res.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 { Self {
@ -268,22 +210,22 @@ impl MessageBuilder {
} }
} }
pub fn from_message(msg: &Message) -> Self { pub fn from_message(msg: Message) -> Self {
Self { msg: msg.clone() } Self { msg }
} }
pub fn message(mut self, msg: String) -> Self { pub fn message(mut self, msg: &str) -> Self {
self.msg.0.push(MessageSection { self.msg.0.push(MessageSection {
msg, 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: String) { pub fn message_mut(&mut self, msg: &str) {
self.msg.0.push(MessageSection { self.msg.0.push(MessageSection {
msg, msg: msg.to_string(),
fgcolor: Color(0xee, 0xee, 0xee), fgcolor: Color(0xee, 0xee, 0xee),
bgcolor: Color(0, 0, 0), bgcolor: Color(0, 0, 0),
}); });

View File

@ -0,0 +1 @@
pub mod string;

View File

@ -0,0 +1,38 @@
use alloc::string::{String, ToString};
#[macro_export]
macro_rules! format {
( $s : expr, $( $e : expr ),* ) => {{
use crate::libk::string::format::Format;
let mut res = $s.to_string();
$(
res.format($e);
)*
res
}};
() => {};
}
pub trait Format<T: ToString> {
fn format(&mut self, f: T);
}
impl<T: ToString> Format<T> for String {
fn format(&mut self, f: T) {
let mut res = String::new();
let mut formatting = false;
for c in self.chars().into_iter() {
if c == '{' {
formatting = true;
res += &f.to_string();
} else if c == '}' {
formatting = false;
}
if !formatting {
res.push(c);
}
}
self.clear();
self.push_str(&res);
}
}

1
src/libk/string/mod.rs Normal file
View File

@ -0,0 +1 @@
pub mod format;