From dafd2e9f98e02cb1796dfda55cbf312bc30c6012 Mon Sep 17 00:00:00 2001
From: Wren Turkal <wt@penguintechs.org>
Date: Sat, 8 Aug 2020 02:18:28 -0700
Subject: [PATCH] Add a way to customize how logging is done.

Each architecture may have a different method to enable logging. Now
that can be customized with a function passed to the init_logger
function.

Also, provide a minimal x86_64 implementation.

This is the first commit where you can see logging coming from the log
crate.

Signed-off-by: Wren Turkal <wt@penguintechs.org>
---
 src/arch/x86_64/start.rs |  2 +-
 src/log.rs               | 26 ++++++++++++++++++++------
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/src/arch/x86_64/start.rs b/src/arch/x86_64/start.rs
index 45f36b32..1f48db88 100644
--- a/src/arch/x86_64/start.rs
+++ b/src/arch/x86_64/start.rs
@@ -84,7 +84,7 @@ pub unsafe extern fn kstart(args_ptr: *const KernelArgs) -> ! {
         KERNEL_SIZE.store(kernel_size, Ordering::SeqCst);
 
         // Initialize logger
-        log::init_logger();
+        log::init_logger(|r| println!("{}:{} -- {}", r.target(), r.level(), r.args()));
 
         info!("Redox OS starting...");
         println!("Kernel: {:X}:{:X}", kernel_base, kernel_base + kernel_size);
diff --git a/src/log.rs b/src/log.rs
index a33afc50..e1dd1aa7 100644
--- a/src/log.rs
+++ b/src/log.rs
@@ -1,4 +1,5 @@
 use alloc::collections::VecDeque;
+use core::sync::atomic::{AtomicBool, Ordering};
 use spin::Mutex;
 
 pub static LOG: Mutex<Option<Log>> = Mutex::new(None);
@@ -36,6 +37,7 @@ impl Log {
 
 struct RedoxLogger {
     log_func: fn(&log::Record),
+    pub initialized: AtomicBool,
 }
 
 impl ::log::Log for RedoxLogger {
@@ -48,14 +50,26 @@ impl ::log::Log for RedoxLogger {
     fn flush(&self) {}
 }
 
-pub fn init_logger() {
-    ::log::set_max_level(::log::LevelFilter::Info);
-    match ::log::set_logger(&LOGGER) {
-        Ok(_) => ::log::info!("Logger initialized."),
-        Err(e) => println!("Logger setup failed! error: {}", e),
+pub fn init_logger(func: fn(&log::Record)) {
+    unsafe {
+        match LOGGER.initialized.load(Ordering::SeqCst) {
+            false => {
+                ::log::set_max_level(::log::LevelFilter::Info);
+                    LOGGER.log_func = func;
+                    match ::log::set_logger(&LOGGER) {
+                        Ok(_) => ::log::info!("Logger initialized."),
+                        Err(e) => println!("Logger setup failed! error: {}", e),
+                    }
+                LOGGER.initialized.store(true, Ordering::SeqCst);
+            },
+            true => ::log::info!("Tried to reinitialize the logger, which is not possible. Ignoring."),
+        }
     }
 }
 
-static LOGGER: RedoxLogger = RedoxLogger { log_func: |_| {} };
+static mut LOGGER: RedoxLogger = RedoxLogger {
+    log_func: |_| {},
+    initialized: AtomicBool::new(false),
+};
 
 pub use log::{debug, error, info, set_max_level, warn};
-- 
GitLab