From dca1d92a4884796b98a13d4e9a8d4015502a3f88 Mon Sep 17 00:00:00 2001 From: Finn Behrens Date: Sun, 4 Oct 2020 11:16:47 +0200 Subject: [PATCH] add eprintln macro --- build.rs | 7 +++++++ hello-world/Kbuild | 1 + hello-world/src/lib.rs | 2 ++ src/printk.rs | 42 +++++++++++++++++++++++++++++++++++++----- 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/build.rs b/build.rs index 9358ad4c..e6b24540 100644 --- a/build.rs +++ b/build.rs @@ -39,7 +39,14 @@ const INCLUDED_VARS: &[&str] = &[ "FS_USERNS_MOUNT", "FS_RENAME_DOES_D_MOVE", "BINDINGS_GFP_KERNEL", + "KERN_EMERG", + "KERN_ALERT", + "KERN_CRIT", + "KERN_ERR", + "KERN_WARNING", + "KERN_NOTICE", "KERN_INFO", + "KERN_DEBUG", "VERIFY_WRITE", "LINUX_VERSION_CODE", "SEEK_SET", diff --git a/hello-world/Kbuild b/hello-world/Kbuild index 81d6dc88..41039a58 100644 --- a/hello-world/Kbuild +++ b/hello-world/Kbuild @@ -4,6 +4,7 @@ helloworld-objs := hello_world.rust.o CARGO ?= cargo export c_flags +export KDIR $(src)/target/x86_64-linux-kernel/debug/libhello_world.a: cargo_will_determine_dependencies cd $(src); $(CARGO) build -Z build-std=core,alloc --target=x86_64-linux-kernel diff --git a/hello-world/src/lib.rs b/hello-world/src/lib.rs index 9622f432..3ced1458 100644 --- a/hello-world/src/lib.rs +++ b/hello-world/src/lib.rs @@ -6,6 +6,7 @@ use alloc::borrow::ToOwned; use alloc::string::String; use linux_kernel_module::println; +use linux_kernel_module::eprintln; struct HelloWorldModule { message: String, @@ -24,6 +25,7 @@ impl Drop for HelloWorldModule { fn drop(&mut self) { println!("My message is {}", self.message); println!("Goodbye kernel module!"); + eprintln!("Module unloaded"); } } diff --git a/src/printk.rs b/src/printk.rs index 4c94c3fe..2c0e7b7f 100644 --- a/src/printk.rs +++ b/src/printk.rs @@ -4,12 +4,23 @@ use core::fmt; use crate::bindings; use crate::c_types::c_int; +pub use crate::bindings::{ + KERN_EMERG, + KERN_ALERT, + KERN_CRIT, + KERN_ERR, + KERN_WARNING, + KERN_NOTICE, + KERN_INFO, + KERN_DEBUG +}; + #[doc(hidden)] -pub fn printk(s: &[u8]) { +pub fn printk(s: &[u8], level: &'static [u8; 3usize]) { // Don't copy the trailing NUL from `KERN_INFO`. let mut fmt_str = [0; bindings::KERN_INFO.len() - 1 + b"%.*s\0".len()]; fmt_str[..bindings::KERN_INFO.len() - 1] - .copy_from_slice(&bindings::KERN_INFO[..bindings::KERN_INFO.len() - 1]); + .copy_from_slice(&level[..bindings::KERN_INFO.len() - 1]); fmt_str[bindings::KERN_INFO.len() - 1..].copy_from_slice(b"%.*s\0"); // TODO: I believe printk never fails @@ -56,15 +67,36 @@ impl fmt::Write for LogLineWriter { #[macro_export] macro_rules! println { () => ({ - $crate::printk::printk("\n".as_bytes()); + $crate::printk::printk("\n".as_bytes(), $crate::printk::KERN_INFO); + }); + ($fmt:expr) => ({ + $crate::printk::printk(concat!($fmt, "\n").as_bytes(), $crate::printk::KERN_INFO); + }); + ($fmt:expr, $($arg:tt)*) => ({ + use ::core::fmt; + let mut writer = $crate::printk::LogLineWriter::new(); + let _ = fmt::write(&mut writer, format_args!(concat!($fmt, "\n"), $($arg)*)).unwrap(); + $crate::printk::printk(writer.as_bytes(), $crate::printk::KERN_INFO); + }); +} + +/// [`eprintln!`] functions the same as it does in `std`, except instead of +/// printing to `stdout`, it writes to the kernel console at the `KERN_ERR` +/// level. +/// +/// [`eprintln!`]: https://doc.rust-lang.org/stable/std/macro.eprintln.html +#[macro_export] +macro_rules! eprintln { + () => ({ + $crate::printk::printk("\n".as_bytes(), $crate::printk::KERN_ERR); }); ($fmt:expr) => ({ - $crate::printk::printk(concat!($fmt, "\n").as_bytes()); + $crate::printk::printk(concat!($fmt, "\n").as_bytes(), $crate::printk::KERN_ERR); }); ($fmt:expr, $($arg:tt)*) => ({ use ::core::fmt; let mut writer = $crate::printk::LogLineWriter::new(); let _ = fmt::write(&mut writer, format_args!(concat!($fmt, "\n"), $($arg)*)).unwrap(); - $crate::printk::printk(writer.as_bytes()); + $crate::printk::printk(writer.as_bytes(), $crate::printk::KERN_ERR); }); }