@@ -6,13 +6,18 @@ use core::fmt;
66use crate :: bindings;
77use crate :: c_types:: c_int;
88
9+ pub use crate :: bindings:: {
10+ KERN_ALERT , KERN_CRIT , KERN_DEBUG , KERN_EMERG , KERN_ERR , KERN_INFO , KERN_NOTICE , KERN_WARNING ,
11+ } ;
12+
13+ const LEVEL_LEN : usize = 3 ;
14+
915#[ doc( hidden) ]
10- pub fn printk ( s : & [ u8 ] ) {
16+ pub fn printk ( s : & [ u8 ] , level : & ' static [ u8 ; LEVEL_LEN ] ) {
1117 // Don't copy the trailing NUL from `KERN_INFO`.
12- let mut fmt_str = [ 0 ; bindings:: KERN_INFO . len ( ) - 1 + b"%.*s\0 " . len ( ) ] ;
13- fmt_str[ ..bindings:: KERN_INFO . len ( ) - 1 ]
14- . copy_from_slice ( & bindings:: KERN_INFO [ ..bindings:: KERN_INFO . len ( ) - 1 ] ) ;
15- fmt_str[ bindings:: KERN_INFO . len ( ) - 1 ..] . copy_from_slice ( b"%.*s\0 " ) ;
18+ let mut fmt_str = [ 0 ; LEVEL_LEN - 1 + b"%.*s\0 " . len ( ) ] ;
19+ fmt_str[ ..LEVEL_LEN - 1 ] . copy_from_slice ( & level[ ..LEVEL_LEN - 1 ] ) ;
20+ fmt_str[ LEVEL_LEN - 1 ..] . copy_from_slice ( b"%.*s\0 " ) ;
1621
1722 // TODO: I believe printk never fails
1823 unsafe { bindings:: printk ( fmt_str. as_ptr ( ) as _ , s. len ( ) as c_int , s. as_ptr ( ) ) } ;
@@ -50,6 +55,33 @@ impl fmt::Write for LogLineWriter {
5055 }
5156}
5257
58+ /// [`kprintln!`] prints to the kernel console with a given level.
59+ /// If no level is given, it will default to `KERN_INFO`.
60+ #[ macro_export]
61+ macro_rules! kprintln {
62+ ( ) => ( {
63+ kprintln!( level: $crate:: printk:: KERN_INFO ) ;
64+ } ) ;
65+ ( level: $level: expr) => ( {
66+ $crate:: printk:: printk( "\n " . as_bytes( ) , $level) ;
67+ } ) ;
68+ ( $msg: expr) => ( {
69+ kprintln!( level: $crate:: printk:: KERN_INFO , $msg) ;
70+ } ) ;
71+ ( level: $level: expr, $msg: expr) => ( {
72+ $crate:: printk:: printk( concat!( $msg, "\n " ) . as_bytes( ) , $level) ;
73+ } ) ;
74+ ( level: $level: expr, $fmt: expr, $( $arg: tt) * ) => ( {
75+ use :: core:: fmt;
76+ let mut writer = $crate:: printk:: LogLineWriter :: new( ) ;
77+ let _ = fmt:: write( & mut writer, format_args!( concat!( $fmt, "\n " ) , $( $arg) * ) ) . unwrap( ) ;
78+ $crate:: printk:: printk( writer. as_bytes( ) , $crate:: printk:: KERN_INFO ) ;
79+ } ) ;
80+ ( $fmt: expr, $( $arg: tt) * ) => ( {
81+ kprintln!( level: $crate:: printk:: KERN_INFO , $fmt, $( $arg) * ) ;
82+ } ) ;
83+ }
84+
5385/// [`println!`] functions the same as it does in `std`, except instead of
5486/// printing to `stdout`, it writes to the kernel console at the `KERN_INFO`
5587/// level.
@@ -58,15 +90,30 @@ impl fmt::Write for LogLineWriter {
5890#[ macro_export]
5991macro_rules! println {
6092 ( ) => ( {
61- $crate:: printk:: printk ( " \n " . as_bytes ( ) ) ;
93+ kprintln! ( level : $crate:: printk:: KERN_INFO ) ;
6294 } ) ;
63- ( $fmt : expr) => ( {
64- $crate:: printk:: printk ( concat! ( $fmt , " \n " ) . as_bytes ( ) ) ;
95+ ( $msg : expr) => ( {
96+ kprintln! ( level : $crate:: printk:: KERN_INFO , $msg ) ;
6597 } ) ;
6698 ( $fmt: expr, $( $arg: tt) * ) => ( {
67- use :: core:: fmt;
68- let mut writer = $crate:: printk:: LogLineWriter :: new( ) ;
69- let _ = fmt:: write( & mut writer, format_args!( concat!( $fmt, "\n " ) , $( $arg) * ) ) . unwrap( ) ;
70- $crate:: printk:: printk( writer. as_bytes( ) ) ;
99+ kprintln!( level: $crate:: printk:: KERN_INFO , $fmt, $( $arg) * ) ;
100+ } ) ;
101+ }
102+
103+ /// [`eprintln!`] functions the same as it does in `std`, except instead of
104+ /// printing to `stderr`, it writes to the kernel console at the `KERN_ERR`
105+ /// level.
106+ ///
107+ /// [`eprintln!`]: https://doc.rust-lang.org/stable/std/macro.eprintln.html
108+ #[ macro_export]
109+ macro_rules! eprintln {
110+ ( ) => ( {
111+ kprintln!( level: $crate:: printk:: KERN_ERR ) ;
112+ } ) ;
113+ ( $msg: expr) => ( {
114+ kprintln!( level: $crate:: printk:: KERN_ERR , $msg) ;
115+ } ) ;
116+ ( $fmt: expr, $( $arg: tt) * ) => ( {
117+ kprintln!( level: $crate:: printk:: KERN_ERR , $msg, $( $arg) * ) ;
71118 } ) ;
72119}
0 commit comments