@@ -6,13 +6,18 @@ use core::fmt;
6
6
use crate :: bindings;
7
7
use crate :: c_types:: c_int;
8
8
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
+
9
15
#[ doc( hidden) ]
10
- pub fn printk ( s : & [ u8 ] ) {
16
+ pub fn printk ( s : & [ u8 ] , level : & ' static [ u8 ; LEVEL_LEN ] ) {
11
17
// 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 " ) ;
16
21
17
22
// TODO: I believe printk never fails
18
23
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 {
50
55
}
51
56
}
52
57
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
+
53
85
/// [`println!`] functions the same as it does in `std`, except instead of
54
86
/// printing to `stdout`, it writes to the kernel console at the `KERN_INFO`
55
87
/// level.
@@ -58,15 +90,30 @@ impl fmt::Write for LogLineWriter {
58
90
#[ macro_export]
59
91
macro_rules! println {
60
92
( ) => ( {
61
- $crate:: printk:: printk ( " \n " . as_bytes ( ) ) ;
93
+ kprintln! ( level : $crate:: printk:: KERN_INFO ) ;
62
94
} ) ;
63
- ( $fmt : expr) => ( {
64
- $crate:: printk:: printk ( concat! ( $fmt , " \n " ) . as_bytes ( ) ) ;
95
+ ( $msg : expr) => ( {
96
+ kprintln! ( level : $crate:: printk:: KERN_INFO , $msg ) ;
65
97
} ) ;
66
98
( $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) * ) ;
71
118
} ) ;
72
119
}
0 commit comments