1 use core::{ 2 fmt::{self, Write}, 3 sync::atomic::Ordering, 4 }; 5 6 use alloc::string::ToString; 7 use log::{info, Log}; 8 9 use super::lib_ui::textui::{textui_putstr, FontColor}; 10 11 use crate::{ 12 driver::tty::{ 13 tty_driver::TtyOperation, tty_port::tty_port, 14 virtual_terminal::virtual_console::CURRENT_VCNUM, 15 }, 16 filesystem::procfs::{ 17 kmsg::KMSG, 18 log::{LogLevel, LogMessage}, 19 }, 20 time::PosixTimeSpec, 21 }; 22 23 #[macro_export] 24 macro_rules! print { 25 ($($arg:tt)*) => ($crate::libs::printk::__printk(format_args!($($arg)*))); 26 } 27 28 #[macro_export] 29 macro_rules! println { 30 () => { 31 $crate::print!("\n"); 32 }; 33 ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*))); 34 } 35 36 #[macro_export] 37 macro_rules! kdebug { 38 ($($arg:tt)*) => { 39 $crate::libs::printk::Logger.log(7,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))); 40 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("[ DEBUG ] ({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))) 41 } 42 } 43 44 #[macro_export] 45 macro_rules! kinfo { 46 ($($arg:tt)*) => { 47 $crate::libs::printk::Logger.log(6,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))); 48 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("[ INFO ] ({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))) 49 } 50 } 51 52 #[macro_export] 53 macro_rules! kwarn { 54 ($($arg:tt)*) => { 55 $crate::libs::printk::Logger.log(4,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))); 56 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("\x1B[1;33m[ WARN ] \x1B[0m")); 57 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))); 58 } 59 } 60 61 #[macro_export] 62 macro_rules! kerror { 63 ($($arg:tt)*) => { 64 $crate::libs::printk::Logger.log(3,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))); 65 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("\x1B[41m[ ERROR ] \x1B[0m")); 66 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))); 67 } 68 } 69 70 #[macro_export] 71 macro_rules! kBUG { 72 ($($arg:tt)*) => { 73 $crate::libs::printk::Logger.log(1,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))); 74 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("\x1B[41m[ BUG ] \x1B[0m")); 75 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))); 76 } 77 } 78 79 pub struct PrintkWriter; 80 81 impl PrintkWriter { 82 #[inline] 83 pub fn __write_fmt(&mut self, args: fmt::Arguments) { 84 self.write_fmt(args).ok(); 85 } 86 87 /// 并输出白底黑字 88 /// @param str: 要写入的字符 89 pub fn __write_string(&mut self, s: &str) { 90 let current_vcnum = CURRENT_VCNUM.load(Ordering::SeqCst); 91 if current_vcnum != -1 { 92 // tty已经初始化了之后才输出到屏幕 93 let port = tty_port(current_vcnum as usize); 94 let tty = port.port_data().internal_tty(); 95 if let Some(tty) = tty { 96 let _ = tty.write(tty.core(), s.as_bytes(), s.len()); 97 } else { 98 let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK); 99 } 100 } else { 101 let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK); 102 } 103 } 104 } 105 106 /// 为Printk Writer实现core::fmt::Write, 使得能够借助Rust自带的格式化组件,格式化字符并输出 107 impl fmt::Write for PrintkWriter { 108 fn write_str(&mut self, s: &str) -> fmt::Result { 109 self.__write_string(s); 110 Ok(()) 111 } 112 } 113 114 #[doc(hidden)] 115 pub fn __printk(args: fmt::Arguments) { 116 PrintkWriter.write_fmt(args).unwrap(); 117 } 118 119 pub struct Logger; 120 121 impl Logger { 122 pub fn log(&self, log_level: usize, message: fmt::Arguments) { 123 if unsafe { KMSG.is_some() } { 124 let timestamp: PosixTimeSpec = PosixTimeSpec::now_cpu_time(); 125 let log_level = LogLevel::from(log_level); 126 127 let log_message = LogMessage::new(timestamp, log_level, message.to_string()); 128 129 unsafe { KMSG.as_ref().unwrap().lock_irqsave().push(log_message) }; 130 } 131 } 132 } 133 134 /// 内核自定义日志器 135 /// 136 /// todo: 完善他的功能,并且逐步把kinfo等宏,迁移到这个logger上面来。 137 struct CustomLogger; 138 139 impl Log for CustomLogger { 140 fn enabled(&self, _metadata: &log::Metadata) -> bool { 141 // 这里可以自定义日志过滤规则 142 true 143 } 144 145 fn log(&self, record: &log::Record) { 146 if self.enabled(record.metadata()) { 147 // todo: 接入kmsg 148 149 writeln!( 150 PrintkWriter, 151 "[ {} ] {} ({}:{}) {}", 152 record.level(), 153 record.target(), 154 record.file().unwrap_or(""), 155 record.line().unwrap_or(0), 156 record.args() 157 ) 158 .unwrap(); 159 } 160 } 161 162 fn flush(&self) { 163 // 如果需要的话,可以在这里实现缓冲区刷新逻辑 164 } 165 } 166 167 pub fn early_init_logging() { 168 log::set_logger(&CustomLogger).unwrap(); 169 log::set_max_level(log::LevelFilter::Debug); 170 info!("Logging initialized"); 171 } 172