Skip to content

Commit 1a6f692

Browse files
committed
add eprintln macro
Signed-off-by: Finn Behrens <[email protected]>
1 parent c17d290 commit 1a6f692

File tree

4 files changed

+58
-18
lines changed

4 files changed

+58
-18
lines changed

drivers/char/rust_example/src/lib.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ struct RustExample {
3232
impl KernelModule for RustExample {
3333
fn init() -> KernelResult<Self> {
3434
println!("Rust Example (init)");
35-
println!("Am I built-in? {}", !cfg!(MODULE));
35+
println!(
36+
level: kernel::printk::KERN_DEBUG,
37+
"Am I built-in? {}",
38+
!cfg!(MODULE)
39+
);
3640
println!("Parameters:");
3741
println!(" my_bool: {}", my_bool.read());
3842
println!(" my_i32: {}", my_i32.read());
@@ -45,7 +49,6 @@ impl KernelModule for RustExample {
4549
impl Drop for RustExample {
4650
fn drop(&mut self) {
4751
println!("My message is {}", self.message);
48-
println!("Rust Example (exit)");
52+
eprintln!("Rust Example (exit)");
4953
}
5054
}
51-

rust/kernel/build.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,14 @@ const INCLUDED_VARS: &[&str] = &[
4040
"FS_USERNS_MOUNT",
4141
"FS_RENAME_DOES_D_MOVE",
4242
"BINDINGS_GFP_KERNEL",
43+
"KERN_EMERG",
44+
"KERN_ALERT",
45+
"KERN_CRIT",
46+
"KERN_ERR",
47+
"KERN_WARNING",
48+
"KERN_NOTICE",
4349
"KERN_INFO",
50+
"KERN_DEBUG",
4451
"VERIFY_WRITE",
4552
"LINUX_VERSION_CODE",
4653
"SEEK_SET",

rust/kernel/src/prelude.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,4 @@ pub use alloc::{
99

1010
pub use module::module;
1111

12-
pub use super::{
13-
println,
14-
KernelResult,
15-
KernelModule,
16-
};
17-
12+
pub use super::{eprintln, println, KernelModule, KernelResult};

rust/kernel/src/printk.rs

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,18 @@ use core::fmt;
66
use crate::bindings;
77
use 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()) };
@@ -52,21 +57,51 @@ impl fmt::Write for LogLineWriter {
5257

5358
/// [`println!`] functions the same as it does in `std`, except instead of
5459
/// printing to `stdout`, it writes to the kernel console at the `KERN_INFO`
55-
/// level.
60+
/// level. Level can be overwritten with the argument level.
5661
///
5762
/// [`println!`]: https://doc.rust-lang.org/stable/std/macro.println.html
5863
#[macro_export]
5964
macro_rules! println {
6065
() => ({
61-
$crate::printk::printk("\n".as_bytes());
66+
println!(level: $crate::printk::KERN_INFO);
67+
});
68+
(level: $level:expr) => ({
69+
$crate::printk::printk("\n".as_bytes(), $level);
70+
});
71+
($msg:expr) => ({
72+
println!(level: $crate::printk::KERN_INFO, $msg);
73+
});
74+
(level: $level:expr, $msg:expr) => ({
75+
$crate::printk::printk(concat!($msg, "\n").as_bytes(), $level);
76+
});
77+
(level: $level:expr, $fmt:expr, $($arg:tt)*) => ({
78+
use ::core::fmt;
79+
let mut writer = $crate::printk::LogLineWriter::new();
80+
let _ = fmt::write(&mut writer, format_args!(concat!($fmt, "\n"), $($arg)*)).unwrap();
81+
$crate::printk::printk(writer.as_bytes(), $crate::printk::KERN_INFO);
82+
});
83+
($fmt:expr, $($arg:tt)*) => ({
84+
println!(level: $crate::printk::KERN_INFO, $fmt, $($arg)*);
85+
});
86+
}
87+
88+
/// [`eprintln!`] functions the same as it does in `std`, except instead of
89+
/// printing to `stderr`, it writes to the kernel console at the `KERN_ERR`
90+
/// level.
91+
///
92+
/// [`eprintln!`]: https://doc.rust-lang.org/stable/std/macro.eprintln.html
93+
#[macro_export]
94+
macro_rules! eprintln {
95+
() => ({
96+
$crate::printk::printk("\n".as_bytes(), $crate::printk::KERN_ERR);
6297
});
6398
($fmt:expr) => ({
64-
$crate::printk::printk(concat!($fmt, "\n").as_bytes());
99+
$crate::printk::printk(concat!($fmt, "\n").as_bytes(), $crate::printk::KERN_ERR);
65100
});
66101
($fmt:expr, $($arg:tt)*) => ({
67102
use ::core::fmt;
68103
let mut writer = $crate::printk::LogLineWriter::new();
69104
let _ = fmt::write(&mut writer, format_args!(concat!($fmt, "\n"), $($arg)*)).unwrap();
70-
$crate::printk::printk(writer.as_bytes());
105+
$crate::printk::printk(writer.as_bytes(), $crate::printk::KERN_ERR);
71106
});
72107
}

0 commit comments

Comments
 (0)