Skip to content
This repository has been archived by the owner on Mar 7, 2021. It is now read-only.

add eprintln macro #273

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions hello-world/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions hello-world/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ extern crate alloc;
use alloc::borrow::ToOwned;
use alloc::string::String;

use linux_kernel_module::eprintln;
use linux_kernel_module::println;

struct HelloWorldModule {
Expand All @@ -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");
}
}

Expand Down
35 changes: 30 additions & 5 deletions src/printk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ use core::fmt;
use crate::bindings;
use crate::c_types::c_int;

pub use crate::bindings::{
KERN_ALERT, KERN_CRIT, KERN_DEBUG, KERN_EMERG, KERN_ERR, KERN_INFO, KERN_NOTICE, KERN_WARNING,
};

#[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
Expand Down Expand Up @@ -56,15 +60,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);
});
}