Skip to content

Commit cc175e9

Browse files
committed
add eprintln macro
Signed-off-by: Finn Behrens <me@kloenk.de>
1 parent c17d290 commit cc175e9

File tree

4 files changed

+74
-25
lines changed

4 files changed

+74
-25
lines changed

drivers/char/rust_example/src/lib.rs

+6-3
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+
kprintln!(
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

+7
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

+2-10
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,8 @@
22

33
//! The `kernel` prelude
44
5-
pub use alloc::{
6-
string::String,
7-
borrow::ToOwned,
8-
};
5+
pub use alloc::{borrow::ToOwned, string::String};
96

107
pub use module::module;
118

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

rust/kernel/src/printk.rs

+59-12
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()) };
@@ -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]
5991
macro_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

Comments
 (0)