增加日志消息格式化log!宏,继续实现中断处理函数

This commit is contained in:
pointer-to-bios 2024-05-08 19:59:10 +08:00
parent 3014893c50
commit 1767182065
9 changed files with 254 additions and 212 deletions

View File

@ -40,7 +40,7 @@ typedef void (*interrupt_entry)();
*/ */
#define interrupt_entry_gen(interrupt) \ #define interrupt_entry_gen(interrupt) \
extern void interrupt_entry_##interrupt() extern void interrupt_entry_##interrupt()
#define interrupt_entry_sym(interrupt) \ #define interrupt_entry(interrupt) \
interrupt_entry_##interrupt interrupt_entry_##interrupt
/** /**
@ -78,12 +78,14 @@ typedef void (*interrupt_request)(u64 rip, u64 rsp, u64 errcode);
#define NMI #define NMI
#define BP #define BP
#define OF #define OF
#define BOUND
interrupt_entry_gen(UNSUPPORTED); interrupt_entry_gen(UNSUPPORTED);
interrupt_entry_gen(DE); // irq0 interrupt_entry_gen(DE); // irq0
interrupt_entry_gen(NMI); // irq2 interrupt_entry_gen(NMI); // irq2
interrupt_entry_gen(BP); // irq3 interrupt_entry_gen(BP); // irq3
interrupt_entry_gen(OF); // ira4 interrupt_entry_gen(OF); // irq4
interrupt_entry_gen(BOUND); // irq5
#endif #endif

View File

@ -3,7 +3,6 @@
#include <types.h> #include <types.h>
// 使用UNIX时间戳
/** /**
* @name system_time_get * @name system_time_get
* *
@ -17,8 +16,6 @@
*/ */
usize system_time_get(); usize system_time_get();
// 如果硬件支持更高的计时精度,
// 此函数提供从系统unix时间开始到现在的纳秒为单位的时间
/** /**
* @name system_time_ns_get * @name system_time_ns_get
* *

View File

@ -1,9 +1,10 @@
use crate::{ use crate::{
kernel::{ kernel::{
klog::LoggerLevel,
memm::utils::AddressUtils, memm::utils::AddressUtils,
tty::tty::{Color, FmtMeta, Tty}, tty::tty::{Color, FmtMeta, Tty},
}, },
message, log, message,
}; };
use super::proc::RegisterTexture; use super::proc::RegisterTexture;
@ -21,9 +22,9 @@ unsafe extern "C" fn interrupt_req_UNSUPPORTED(rip: u64, rsp: u64, _errcode: u64
interrupt_rust_enter(); interrupt_rust_enter();
let tty = Tty::from_id(0).unwrap(); let tty = Tty::from_id(0).unwrap();
tty.enable(); tty.enable();
tty.print(message!( tty.print(log!(
"{Panic}: Kernel hit an {Unsupported} interrupt on rip=0x{} and rsp=0x{}.\n", LoggerLevel::Fatal,
FmtMeta::Color(Color::RED), "Kernel hit an {Unsupported} interrupt on rip=0x{} and rsp=0x{}.\n",
FmtMeta::Color(Color::YELLOW), FmtMeta::Color(Color::YELLOW),
FmtMeta::Pointer(rip as usize), FmtMeta::Pointer(rip as usize),
FmtMeta::Pointer(rsp 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() { if rip.is_kernel_space() {
let tty = Tty::from_id(0).unwrap(); let tty = Tty::from_id(0).unwrap();
tty.enable(); tty.enable();
tty.print(message!( tty.print(log!(
"{Warning}: Kernel hit {Divid Error} on rip=0x{} and rsp=0x{}.\n", LoggerLevel::Fatal,
FmtMeta::Color(Color::PURPLE), "Kernel hit {Divid Error} on rip=0x{} and rsp=0x{}.\n",
FmtMeta::Color(Color::YELLOW), FmtMeta::Color(Color::YELLOW),
FmtMeta::Pointer(rip as usize), FmtMeta::Pointer(rip as usize),
FmtMeta::Pointer(rsp 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) {} // unsafe extern "C" fn interrupt_req_NMI(rip: u64, rsp: u64, errcode: u64) {}
#[no_mangle] #[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(); interrupt_rust_enter();
if rip.is_kernel_space() { if rip.is_kernel_space() {
let register_texture = errcode as *const RegisterTexture; let register_texture = errcode as *const RegisterTexture;
let register_texture = &*register_texture; let register_texture = &*register_texture;
let tty = Tty::from_id(0).unwrap(); let tty = Tty::from_id(0).unwrap();
tty.enable(); tty.enable();
tty.print(message!( tty.print(log!(
"{Debug}: Kernel hit breakpoint {0x{}}.\n", LoggerLevel::Debug,
FmtMeta::Color(Color::BLUE), "Kernel hit breakpoint {0x{}}.\n",
FmtMeta::Pointer(rip as usize), FmtMeta::Pointer(rip as usize),
FmtMeta::Color(Color::GREEN) FmtMeta::Color(Color::GREEN)
)); ));
@ -148,4 +149,40 @@ unsafe extern "C" fn interrupt_req_BP(rip: u64, rsp: u64, errcode: u64) {
} }
#[no_mangle] #[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();
}
}

View File

@ -107,3 +107,15 @@ interrupt_entry_OF:
interrupt_entry_leave interrupt_entry_leave
iretq 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

View File

@ -8,22 +8,23 @@ void interrupt_init()
gate_descriptor_t gate; gate_descriptor_t gate;
// 用UNSUPPORTED中断处理程序填充所有中断向量 // 用UNSUPPORTED中断处理程序填充所有中断向量
trap_gate_generate(gate, interrupt_entry_sym(UNSUPPORTED)); trap_gate_generate(gate, interrupt_entry(UNSUPPORTED));
for (usize i = 4; i < 256; i++) for (usize i = 4; i < 256; i++)
{ {
interrupt_register_gate(gate, 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); 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); 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); 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); 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); interrupt_register_gate(gate, 4);
trap_gate_generate(gate, interrupt_entry(BOUND));
interrupt_open(); interrupt_open();
} }

View File

@ -1,7 +1,5 @@
use core::{cmp::Ordering, ops::Sub, time::Duration}; use core::{cmp::Ordering, ops::Sub, time::Duration};
use alloc::{format, string::ToString};
extern "C" { extern "C" {
fn system_time_get() -> usize; fn system_time_get() -> usize;
fn system_time_ns_get() -> usize; fn system_time_ns_get() -> usize;
@ -10,99 +8,14 @@ extern "C" {
#[derive(Debug)] #[derive(Debug)]
pub struct SystemTimeError(Duration); pub struct SystemTimeError(Duration);
#[derive(Clone, Copy, Hash)] #[derive(Clone, Copy, Hash, Default)]
#[derive(Default)]
pub struct SystemTime { pub struct SystemTime {
/// ms
unix_time: usize, unix_time: usize,
/// ns
ns_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 Eq for SystemTime {}
impl PartialEq for SystemTime { impl PartialEq for SystemTime {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
@ -165,3 +78,80 @@ impl SystemTime {
SystemTime::now() - *self 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<SystemTime> 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,
}
}
}

View File

@ -1,9 +1,4 @@
use crate::libk::alloc::vec::Vec; use crate::kernel::tty::tty::{Color, MessageBuilder};
use super::{
clock::time::SystemTime,
tty::tty::{Color, Message, MessageBuilder},
};
#[derive(PartialEq)] #[derive(PartialEq)]
pub enum LoggerLevel { pub enum LoggerLevel {
@ -15,93 +10,58 @@ pub enum LoggerLevel {
Trace, Trace,
} }
pub struct KernelLogger { impl From<LoggerLevel> for MessageBuilder {
fatal_queue: Vec<(SystemTime, Message)>, fn from(value: LoggerLevel) -> Self {
error_queue: Vec<(SystemTime, Message)>, match value {
warning_queue: Vec<(SystemTime, Message)>, LoggerLevel::Fatal => MessageBuilder::new()
info_queue: Vec<(SystemTime, Message)>, .message("Fatal")
debug_queue: Vec<(SystemTime, Message)>, .foreground_color(Color::RED),
trace_queue: Vec<(SystemTime, Message)>, LoggerLevel::Error => MessageBuilder::new()
} .message("Error")
.foreground_color(Color::ORANGE),
impl KernelLogger { LoggerLevel::Warning => MessageBuilder::new()
pub fn new() -> Self { .message("Warning")
Self { .foreground_color(Color::PURPLE),
fatal_queue: Vec::new(), LoggerLevel::Info => MessageBuilder::new()
error_queue: Vec::new(), .message("Info")
warning_queue: Vec::new(), .foreground_color(Color::GREEN),
info_queue: Vec::new(), LoggerLevel::Debug => MessageBuilder::new()
debug_queue: Vec::new(), .message("Debug")
trace_queue: Vec::new(), .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 { #[macro_export]
} macro_rules! log {
( $level : expr, $fmtter : expr ) => {{
impl Iterator for LogIterator { use crate::kernel::tty::tty::(Color, MessageBuilder, FmtMeta);
type Item = Message; MessageBuilder::from_message(
message!("{[{}]} ",
fn next(&mut self) -> Option<Self::Item> { FmtMeta::SystemTime,
todo!() 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()
}};
} }

View File

@ -1,9 +1,12 @@
use core::ptr::null_mut; use core::ptr::null_mut;
use crate::libk::alloc::{ use crate::{
boxed::Box, kernel::clock::time::{SystemDate, SystemTime},
string::{String, ToString}, libk::alloc::{
vec::Vec, boxed::Box,
string::{String, ToString},
vec::Vec,
},
}; };
extern "C" { extern "C" {
@ -303,11 +306,13 @@ impl MessageBuilder {
} }
pub enum FmtMeta { pub enum FmtMeta {
Step,
Color(Color), Color(Color),
String(String), String(String),
ToStringable(Box<dyn ToString>), ToStringable(Box<dyn ToString>),
Hex(u8), Hex(u8),
Pointer(usize), Pointer(usize),
SystemTime,
} }
pub fn format_message(fmt: &mut Vec<char>, meta: FmtMeta) -> MessageBuilder { pub fn format_message(fmt: &mut Vec<char>, meta: FmtMeta) -> MessageBuilder {
@ -343,6 +348,7 @@ pub fn format_message(fmt: &mut Vec<char>, meta: FmtMeta) -> MessageBuilder {
formatter.remove(formatter.len() - 1); formatter.remove(formatter.len() - 1);
formatter.remove(0); formatter.remove(0);
match meta { match meta {
FmtMeta::Step => {}
FmtMeta::Color(color) => { FmtMeta::Color(color) => {
let first = fmt.split_at(fmt_start).0; let first = fmt.split_at(fmt_start).0;
msgbuilder.message_mut(&String::from_iter(first.iter())); msgbuilder.message_mut(&String::from_iter(first.iter()));
@ -372,6 +378,37 @@ pub fn format_message(fmt: &mut Vec<char>, meta: FmtMeta) -> MessageBuilder {
p >>= 4; p >>= 4;
} }
} }
FmtMeta::SystemTime => {
let SystemDate {
year,
month,
day,
hour,
minute,
second,
milisecond,
..
} = SystemDate::from(SystemTime::now());
let put_n_number = |fmt: &mut Vec<char>, 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(); let mut rests = Vec::new();
while !fmt.is_empty() && fmt[0] != '{' { while !fmt.is_empty() && fmt[0] != '{' {

View File

@ -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 { impl ToString for String {
fn to_string(&self) -> String { fn to_string(&self) -> Self {
self.clone() self.clone()
} }
} }