From 17671820658f456d96c76e15bcf36d46397a8247 Mon Sep 17 00:00:00 2001 From: pointer-to-bios Date: Wed, 8 May 2024 19:59:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=97=A5=E5=BF=97=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E6=A0=BC=E5=BC=8F=E5=8C=96log!=E5=AE=8F=EF=BC=8C?= =?UTF-8?q?=E7=BB=A7=E7=BB=AD=E5=AE=9E=E7=8E=B0=E4=B8=AD=E6=96=AD=E5=A4=84?= =?UTF-8?q?=E7=90=86=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel/arch/x86_64/interrupt_procs.h | 12 +- include/kernel/clock/time.h | 3 - src/kernel/arch/x86_64/interrupt.rs | 61 +++++-- src/kernel/arch/x86_64/interrupt_procs.s | 12 ++ src/kernel/arch/x86_64/interrupt_x86_64.c | 13 +- src/kernel/clock/time.rs | 170 +++++++++---------- src/kernel/klog.rs | 142 ++++++---------- src/kernel/tty/tty.rs | 45 ++++- src/libk/alloc/string.rs | 8 +- 9 files changed, 254 insertions(+), 212 deletions(-) diff --git a/include/kernel/arch/x86_64/interrupt_procs.h b/include/kernel/arch/x86_64/interrupt_procs.h index f4a124d..795ecb4 100644 --- a/include/kernel/arch/x86_64/interrupt_procs.h +++ b/include/kernel/arch/x86_64/interrupt_procs.h @@ -40,7 +40,7 @@ typedef void (*interrupt_entry)(); */ #define interrupt_entry_gen(interrupt) \ extern void interrupt_entry_##interrupt() -#define interrupt_entry_sym(interrupt) \ +#define interrupt_entry(interrupt) \ interrupt_entry_##interrupt /** @@ -78,12 +78,14 @@ typedef void (*interrupt_request)(u64 rip, u64 rsp, u64 errcode); #define NMI #define BP #define OF +#define BOUND interrupt_entry_gen(UNSUPPORTED); -interrupt_entry_gen(DE); // irq0 -interrupt_entry_gen(NMI); // irq2 -interrupt_entry_gen(BP); // irq3 -interrupt_entry_gen(OF); // ira4 +interrupt_entry_gen(DE); // irq0 +interrupt_entry_gen(NMI); // irq2 +interrupt_entry_gen(BP); // irq3 +interrupt_entry_gen(OF); // irq4 +interrupt_entry_gen(BOUND); // irq5 #endif diff --git a/include/kernel/clock/time.h b/include/kernel/clock/time.h index b680658..229e94d 100644 --- a/include/kernel/clock/time.h +++ b/include/kernel/clock/time.h @@ -3,7 +3,6 @@ #include -// 使用UNIX时间戳 /** * @name system_time_get * @@ -17,8 +16,6 @@ */ usize system_time_get(); -// 如果硬件支持更高的计时精度, -// 此函数提供从系统unix时间开始到现在的纳秒为单位的时间 /** * @name system_time_ns_get * diff --git a/src/kernel/arch/x86_64/interrupt.rs b/src/kernel/arch/x86_64/interrupt.rs index 19ec192..6bb4af6 100644 --- a/src/kernel/arch/x86_64/interrupt.rs +++ b/src/kernel/arch/x86_64/interrupt.rs @@ -1,9 +1,10 @@ use crate::{ kernel::{ + klog::LoggerLevel, memm::utils::AddressUtils, tty::tty::{Color, FmtMeta, Tty}, }, - message, + log, message, }; use super::proc::RegisterTexture; @@ -21,9 +22,9 @@ 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), + tty.print(log!( + LoggerLevel::Fatal, + "Kernel hit an {Unsupported} interrupt on rip=0x{} and rsp=0x{}.\n", FmtMeta::Color(Color::YELLOW), FmtMeta::Pointer(rip as usize), FmtMeta::Pointer(rsp as usize) @@ -37,9 +38,9 @@ unsafe extern "C" fn interrupt_req_DE(rip: u64, rsp: u64, _errcode: u64) { if rip.is_kernel_space() { 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), + tty.print(log!( + LoggerLevel::Fatal, + "Kernel hit {Divid Error} on rip=0x{} and rsp=0x{}.\n", FmtMeta::Color(Color::YELLOW), FmtMeta::Pointer(rip as usize), FmtMeta::Pointer(rsp as usize) @@ -55,16 +56,16 @@ unsafe extern "C" fn interrupt_req_DE(rip: u64, rsp: u64, _errcode: u64) { // 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) { +unsafe extern "C" fn interrupt_req_BP(rip: u64, _rsp: u64, errcode: u64) { interrupt_rust_enter(); if rip.is_kernel_space() { let register_texture = errcode as *const RegisterTexture; let register_texture = &*register_texture; let tty = Tty::from_id(0).unwrap(); tty.enable(); - tty.print(message!( - "{Debug}: Kernel hit breakpoint {0x{}}.\n", - FmtMeta::Color(Color::BLUE), + tty.print(log!( + LoggerLevel::Debug, + "Kernel hit breakpoint {0x{}}.\n", FmtMeta::Pointer(rip as usize), FmtMeta::Color(Color::GREEN) )); @@ -148,4 +149,40 @@ 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) {} +unsafe extern "C" fn interrupt_req_OF(rip: u64, rsp: u64, _errcode: u64) { + interrupt_rust_enter(); + if rip.is_kernel_space() { + let tty = Tty::from_id(0).unwrap(); + tty.enable(); + tty.print(log!( + LoggerLevel::Fatal, + "Kernel hit {Overflow Error} on rip=0x{} and rsp=0x{}.\n", + FmtMeta::Color(Color::YELLOW), + FmtMeta::Pointer(rip as usize), + FmtMeta::Pointer(rsp as usize) + )); + loop {} + } else if rip.is_user_space() { + // TODO 处理后返回 + interrupt_rust_leave(); + } +} + +#[no_mangle] +unsafe extern "C" fn interrupt_req_BOUND(rip: u64, rsp: u64, _errcode: u64) { + interrupt_rust_enter(); + if rip.is_kernel_space() { + let tty = Tty::from_id(0).unwrap(); + tty.enable(); + tty.print(log!( + LoggerLevel::Fatal, + "Kernel hit {Bound Error} on rip=0x{} and rsp=0x{}.\n", + FmtMeta::Color(Color::YELLOW), + FmtMeta::Pointer(rip as usize), + FmtMeta::Pointer(rsp as usize) + )); + loop {} + } else if rsp.is_user_space() { + interrupt_rust_leave(); + } +} diff --git a/src/kernel/arch/x86_64/interrupt_procs.s b/src/kernel/arch/x86_64/interrupt_procs.s index 968ff49..a572601 100644 --- a/src/kernel/arch/x86_64/interrupt_procs.s +++ b/src/kernel/arch/x86_64/interrupt_procs.s @@ -107,3 +107,15 @@ interrupt_entry_OF: interrupt_entry_leave iretq + + global interrupt_entry_BOUND + extern interrupt_req_BOUND +interrupt_entry_BOUND: + interrupt_entry_enter + + mov rdi, [rsp + 128] + mov rsi, [rsp + 152] + call interrupt_req_BOUND + + interrupt_entry_leave + iretq diff --git a/src/kernel/arch/x86_64/interrupt_x86_64.c b/src/kernel/arch/x86_64/interrupt_x86_64.c index 53883ed..337a374 100644 --- a/src/kernel/arch/x86_64/interrupt_x86_64.c +++ b/src/kernel/arch/x86_64/interrupt_x86_64.c @@ -8,22 +8,23 @@ void interrupt_init() gate_descriptor_t gate; // 用UNSUPPORTED中断处理程序填充所有中断向量 - trap_gate_generate(gate, interrupt_entry_sym(UNSUPPORTED)); + trap_gate_generate(gate, interrupt_entry(UNSUPPORTED)); for (usize i = 4; i < 256; i++) { interrupt_register_gate(gate, i); } - trap_gate_generate(gate, interrupt_entry_sym(DE)); + trap_gate_generate(gate, interrupt_entry(DE)); interrupt_register_gate(gate, 0); - trap_gate_generate(gate, interrupt_entry_sym(UNSUPPORTED)); // Debug Exception (#DB) + trap_gate_generate(gate, interrupt_entry(UNSUPPORTED)); // Debug Exception (#DB) nosupport interrupt_register_gate(gate, 1); - trap_gate_generate(gate, interrupt_entry_sym(NMI)); + trap_gate_generate(gate, interrupt_entry(NMI)); interrupt_register_gate(gate, 2); - trap_gate_generate(gate, interrupt_entry_sym(BP)); + trap_gate_generate(gate, interrupt_entry(BP)); interrupt_register_gate(gate, 3); - trap_gate_generate(gate, interrupt_entry_sym(OF)); + trap_gate_generate(gate, interrupt_entry(OF)); interrupt_register_gate(gate, 4); + trap_gate_generate(gate, interrupt_entry(BOUND)); interrupt_open(); } diff --git a/src/kernel/clock/time.rs b/src/kernel/clock/time.rs index 993cedc..390a92e 100644 --- a/src/kernel/clock/time.rs +++ b/src/kernel/clock/time.rs @@ -1,7 +1,5 @@ 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; @@ -10,99 +8,14 @@ extern "C" { #[derive(Debug)] pub struct SystemTimeError(Duration); -#[derive(Clone, Copy, Hash)] -#[derive(Default)] +#[derive(Clone, Copy, Hash, Default)] pub struct SystemTime { + /// ms unix_time: usize, + /// ns 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 { @@ -165,3 +78,80 @@ impl SystemTime { SystemTime::now() - *self } } + +pub struct SystemDate { + pub year: u16, + pub month: u8, + pub day: u8, + pub hour: u8, + pub minute: u8, + pub second: u8, + pub milisecond: u16, + pub nanosecond: u32, +} + +impl From for SystemDate { + fn from( + SystemTime { + mut unix_time, + ns_time, + }: SystemTime, + ) -> Self { + let milisecond = (unix_time % 1000) as u16; + unix_time /= 1000; + let second = (unix_time % 60) as u8; + unix_time /= 60; + let minute = (unix_time % 60) as u8; + unix_time /= 60; + let hour = (unix_time % 24) as u8; + unix_time /= 24; + let (year, leap) = { + let mut year = 1970; + let get_days_of_this_year = |y| { + if (y % 4 == 0 && y % 100 != 0) || y % 400 == 0 { + 366 + } else { + 365 + } + }; + while unix_time > get_days_of_this_year(year) { + unix_time -= get_days_of_this_year(year); + year += 1; + } + (year, (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) + }; + let month = { + let mut month = 0; + let dom = [ + // days of months + 31, + if leap { 29 } else { 28 }, + 31, + 30, + 31, + 30, + 31, + 31, + 30, + 31, + 30, + 31, + ]; + while unix_time > dom[month] { + unix_time -= dom[month]; + month += 1; + } + month as u8 + 1 + }; + Self { + year, + month, + day: unix_time as u8 + 1, + hour, + minute, + second, + milisecond, + nanosecond: ns_time as u32, + } + } +} diff --git a/src/kernel/klog.rs b/src/kernel/klog.rs index 22cb64d..87574d1 100644 --- a/src/kernel/klog.rs +++ b/src/kernel/klog.rs @@ -1,9 +1,4 @@ -use crate::libk::alloc::vec::Vec; - -use super::{ - clock::time::SystemTime, - tty::tty::{Color, Message, MessageBuilder}, -}; +use crate::kernel::tty::tty::{Color, MessageBuilder}; #[derive(PartialEq)] pub enum LoggerLevel { @@ -15,93 +10,58 @@ pub enum LoggerLevel { 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::new(), - error_queue: Vec::new(), - warning_queue: Vec::new(), - info_queue: Vec::new(), - debug_queue: Vec::new(), - trace_queue: Vec::new(), +impl From for MessageBuilder { + fn from(value: LoggerLevel) -> Self { + match value { + LoggerLevel::Fatal => MessageBuilder::new() + .message("Fatal") + .foreground_color(Color::RED), + LoggerLevel::Error => MessageBuilder::new() + .message("Error") + .foreground_color(Color::ORANGE), + LoggerLevel::Warning => MessageBuilder::new() + .message("Warning") + .foreground_color(Color::PURPLE), + LoggerLevel::Info => MessageBuilder::new() + .message("Info") + .foreground_color(Color::GREEN), + LoggerLevel::Debug => MessageBuilder::new() + .message("Debug") + .foreground_color(Color::BLUE), + LoggerLevel::Trace => MessageBuilder::new() + .message("Trace") + .foreground_color(Color::YELLOW), } } - - 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 { - todo!() - } } -pub struct LogIterator { -} - -impl Iterator for LogIterator { - type Item = Message; - - fn next(&mut self) -> Option { - todo!() - } +#[macro_export] +macro_rules! log { + ( $level : expr, $fmtter : expr ) => {{ + use crate::kernel::tty::tty::(Color, MessageBuilder, FmtMeta); + MessageBuilder::from_message( + message!("{[{}]} ", + FmtMeta::SystemTime, + FmtMeta::Color(Color::GRAY) + )) + .append(MessageBuilder::from($level)) + .append( + MessageBuilder::new() + .message(": ") + .message($fmtter) + ) + .build() + }}; + ( $level : expr, $fmtter : expr, $( $e : expr ),* ) => {{ + use crate::kernel::tty::tty::{Color, MessageBuilder, FmtMeta}; + MessageBuilder::from_message( + message!("{[{}]} ", + FmtMeta::SystemTime, + FmtMeta::Color(Color::GRAY) + )) + .append(MessageBuilder::from($level)) + .append(MessageBuilder::new().message(": ")) + .append(MessageBuilder::from_message(message!($fmtter, $( $e ),*))) + .build() + }}; } diff --git a/src/kernel/tty/tty.rs b/src/kernel/tty/tty.rs index 3fd0490..d0b4696 100644 --- a/src/kernel/tty/tty.rs +++ b/src/kernel/tty/tty.rs @@ -1,9 +1,12 @@ use core::ptr::null_mut; -use crate::libk::alloc::{ - boxed::Box, - string::{String, ToString}, - vec::Vec, +use crate::{ + kernel::clock::time::{SystemDate, SystemTime}, + libk::alloc::{ + boxed::Box, + string::{String, ToString}, + vec::Vec, + }, }; extern "C" { @@ -303,11 +306,13 @@ impl MessageBuilder { } pub enum FmtMeta { + Step, Color(Color), String(String), ToStringable(Box), Hex(u8), Pointer(usize), + SystemTime, } pub fn format_message(fmt: &mut Vec, meta: FmtMeta) -> MessageBuilder { @@ -343,6 +348,7 @@ pub fn format_message(fmt: &mut Vec, meta: FmtMeta) -> MessageBuilder { formatter.remove(formatter.len() - 1); formatter.remove(0); match meta { + FmtMeta::Step => {} FmtMeta::Color(color) => { let first = fmt.split_at(fmt_start).0; msgbuilder.message_mut(&String::from_iter(first.iter())); @@ -372,6 +378,37 @@ pub fn format_message(fmt: &mut Vec, meta: FmtMeta) -> MessageBuilder { p >>= 4; } } + FmtMeta::SystemTime => { + let SystemDate { + year, + month, + day, + hour, + minute, + second, + milisecond, + .. + } = SystemDate::from(SystemTime::now()); + let put_n_number = |fmt: &mut Vec, mut data, n| { + for _ in 0..n { + fmt.insert(fmt_start, ((data % 10) as u8 + b'0') as char); + data /= 10; + } + }; + put_n_number(fmt, milisecond / 10, 2); + fmt.insert(fmt_start, '.'); + put_n_number(fmt, second as u16, 2); + fmt.insert(fmt_start, ':'); + put_n_number(fmt, minute as u16, 2); + fmt.insert(fmt_start, ':'); + put_n_number(fmt, hour as u16, 2); + fmt.insert(fmt_start, ' '); + put_n_number(fmt, day as u16, 2); + fmt.insert(fmt_start, '-'); + put_n_number(fmt, month as u16, 2); + fmt.insert(fmt_start, '-'); + put_n_number(fmt, year, 4); + } } let mut rests = Vec::new(); while !fmt.is_empty() && fmt[0] != '{' { diff --git a/src/libk/alloc/string.rs b/src/libk/alloc/string.rs index 7028484..070fba0 100644 --- a/src/libk/alloc/string.rs +++ b/src/libk/alloc/string.rs @@ -57,8 +57,14 @@ impl<'a> FromIterator<&'a char> for String { } } +impl From<&str> for String { + fn from(value: &str) -> Self { + Self::from_iter(value.chars()) + } +} + impl ToString for String { - fn to_string(&self) -> String { + fn to_string(&self) -> Self { self.clone() } }