diff --git a/.cargo/runner.sh b/.cargo/runner.sh
index 15d0dddfcc60d765d8109d686bd24be9a385e3a8..e66833b774f66418285d8f9a737ee97127d47376 100755
--- a/.cargo/runner.sh
+++ b/.cargo/runner.sh
@@ -43,8 +43,9 @@ if [ "$(basename $KERNEL)" = "hyperion" ]; then
     qemu-system-x86_64 \
         -enable-kvm \
         -machine q35 \
-        -cpu qemu64 \
+        -cpu qemu64,+rdrand,+rdseed \
         -smp 8 \
+        -m 512m \
         -M smm=off \
         -d int,guest_errors,cpu_reset \
         -no-reboot \
@@ -59,8 +60,9 @@ else
     qemu-system-x86_64 \
         -enable-kvm \
         -machine q35 \
-        -cpu qemu64 \
+        -cpu qemu64,+rdrand,+rdseed \
         -smp 8 \
+        -m 512m \
         -M smm=off \
         -d int,guest_errors,cpu_reset \
         -device isa-debug-exit,iobase=0xf4,iosize=0x04 \
diff --git a/TODO.md b/TODO.md
new file mode 100644
index 0000000000000000000000000000000000000000..4ceff496ab83a79a4eb72e91b048ea6c6f4f5510
--- /dev/null
+++ b/TODO.md
@@ -0,0 +1,15 @@
+# TODOs:
+
+ - GDT + IDT for non-boot SMP CPU:s
+
+ - Font generator proc macro
+
+   - With cache of course
+
+ - Memory manager
+
+   - Physical memory allocator
+
+   - Virtual memory manager
+
+ - APIC
diff --git a/src/arch/x86_64/mod.rs b/src/arch/x86_64/mod.rs
index 7a415c331fc6b6a9ef06f96952297f24054b183b..4078b80d88139170cc195ea24130025afd5dfd72 100644
--- a/src/arch/x86_64/mod.rs
+++ b/src/arch/x86_64/mod.rs
@@ -1,4 +1,5 @@
-use crate::debug;
+use crate::{debug, error};
+use x86_64::instructions::random::RdRand;
 
 //
 
@@ -17,6 +18,13 @@ pub fn early_boot_cpu() {
 
 pub fn early_per_cpu() {}
 
+pub fn rng_seed() -> u64 {
+    RdRand::new().and_then(RdRand::get_u64).unwrap_or_else(|| {
+        error!("Failed to generate a rng seed with x86_64 RDSEED");
+        0
+    })
+}
+
 pub fn done() -> ! {
     loop {
         x86_64::instructions::hlt();
diff --git a/src/boot/limine/mod.rs b/src/boot/limine/mod.rs
index 0f7170aaa5d13009367751b6a0ec6f53b0839979..483e3e246e356ec27b6ec2b1fc4b36c66364cb9d 100644
--- a/src/boot/limine/mod.rs
+++ b/src/boot/limine/mod.rs
@@ -1,4 +1,5 @@
-use crate::arch;
+use super::BOOT_NAME;
+use crate::{arch, kernel_main};
 
 //
 
@@ -17,7 +18,7 @@ mod term;
 
 #[no_mangle]
 pub extern "C" fn _start() -> ! {
-    crate::BOOTLOADER.call_once(|| "Limine");
+    BOOT_NAME.call_once(|| "Limine");
 
     framebuffer::init();
     cmdline::init();
@@ -25,7 +26,7 @@ pub extern "C" fn _start() -> ! {
     arch::early_boot_cpu();
     arch::early_per_cpu();
 
-    crate::kernel_main()
+    kernel_main()
 }
 
 pub fn smp_init() {
diff --git a/src/boot/limine/smp.rs b/src/boot/limine/smp.rs
index 74859e1fc2301c8e6581df13fd3e34880768d3a6..29e2e0a5233239727f4aabc0fbc5b9129be78573 100644
--- a/src/boot/limine/smp.rs
+++ b/src/boot/limine/smp.rs
@@ -1,7 +1,4 @@
-use crate::{
-    arch,
-    smp::{smp_main, Cpu},
-};
+use crate::{arch, smp::Cpu, smp_main};
 use limine::{LimineSmpInfo, LimineSmpRequest};
 
 //
diff --git a/src/boot/mod.rs b/src/boot/mod.rs
index f670b8d23fdfb8ead447862081c3bf6eb0a55185..fb80769a21349b4156271995f77cc687f8af263f 100644
--- a/src/boot/mod.rs
+++ b/src/boot/mod.rs
@@ -1,3 +1,7 @@
+use spin::Once;
+
+//
+
 #[cfg(feature = "multiboot1")]
 #[path = "multiboot1/mod.rs"]
 mod boot;
@@ -11,4 +15,11 @@ mod boot;
 #[path = "limine/mod.rs"]
 mod boot;
 
+//
+
 pub use boot::*;
+
+//
+
+/// Name of the detected bootloader
+pub static BOOT_NAME: Once<&'static str> = Once::new();
diff --git a/src/env.rs b/src/env.rs
index 899980f56184962d89d104d7ec4eba22990cafc7..57cc52d5b7f8a142ebb3907df16c5737620715c2 100644
--- a/src/env.rs
+++ b/src/env.rs
@@ -3,8 +3,6 @@ use spin::Once;
 
 //
 
-//
-
 pub fn args() -> Arguments {
     Arguments::get()
 }
@@ -25,7 +23,7 @@ pub struct Arguments {
 impl Arguments {
     pub fn parse(s: &'static str) {
         ARGUMENTS.call_once(|| {
-            let mut iter = s.split_whitespace();
+            let mut iter = s.split(|c: char| c.is_whitespace() || c == '=');
             let mut result = Arguments::default();
             result.cmdline = s;
 
@@ -40,13 +38,6 @@ impl Arguments {
                             }
                         }
                     }
-                    _ if item.starts_with("log=") => {
-                        if let Some(l) = LogLevel::parse(&item[4..]) {
-                            result.log_level = l
-                        } else {
-                            result.had_unrecognized = true
-                        }
-                    }
                     _ => result.had_unrecognized = true,
                 }
             }
diff --git a/src/main.rs b/src/main.rs
index 74becd5a273454bb24443abea98330344bc31aad..7dbe95c4ae83a20014d3292fd01419ffe0b539a3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -7,16 +7,12 @@
 #![feature(result_option_inspect)]
 #![feature(allocator_api)]
 #![feature(nonnull_slice_from_raw_parts)]
+#![feature(exclusive_range_pattern)]
 #![test_runner(crate::testfw::test_runner)]
 #![reexport_test_harness_main = "test_main"]
 
 //
 
-use crate::term::escape::encode::EscapeEncoder;
-use spin::Once;
-
-//
-
 extern crate alloc;
 
 //
@@ -33,19 +29,18 @@ pub mod smp;
 pub mod term;
 #[cfg(test)]
 pub mod testfw;
+pub mod util;
 pub mod video;
 
 //
 
-/// Name of the kernel
-pub static KERNEL: &str = if cfg!(test) {
+pub static KERNEL_NAME: &str = if cfg!(test) {
     "Hyperion-Testing"
 } else {
     "Hyperion"
 };
 
-/// Name of the detected bootloader
-pub static BOOTLOADER: Once<&'static str> = Once::new();
+pub static KERNEL_VERS: &str = env!("CARGO_PKG_VERSION");
 
 //
 
@@ -58,13 +53,22 @@ fn kernel_main() -> ! {
     // ofc. every kernel has to have this cringy ascii name splash
     info!("\n{}\n", include_str!("./splash"));
 
-    if let Some(bl) = BOOTLOADER.get() {
-        let kernel = KERNEL.true_cyan();
-        debug!("{kernel} was booted with {bl}");
+    if let Some(bl) = boot::BOOT_NAME.get() {
+        debug!("{KERNEL_NAME} {KERNEL_VERS} was booted with {bl}");
     }
 
     #[cfg(test)]
     test_main();
 
+    debug!("{}", arch::rng_seed());
+
     smp::init();
 }
+
+fn smp_main(cpu: smp::Cpu) -> ! {
+    debug!("{cpu} entering smp_main");
+
+    // x86_64::instructions::interrupts::int3();
+
+    arch::done();
+}
diff --git a/src/mem.rs b/src/mem.rs
index 61bc690260e7505ac3c7391f454dc43b6dc250fd..af0077cbf6342b300d06eedc15d9b3f63589f4d9 100644
--- a/src/mem.rs
+++ b/src/mem.rs
@@ -1,4 +1,4 @@
-use crate::{boot, debug, error};
+use crate::{boot, debug, error, util::NumberPostfix};
 use core::{
     alloc::{GlobalAlloc, Layout},
     ptr::null_mut,
@@ -13,12 +13,13 @@ pub fn init() {
 
     for Memmap { base, len } in boot::memmap() {
         usable += len;
-        debug!("base: {base:#X} len: {len:#X}");
+        debug!("base: {base:#X} len: {len:#X} ({}B)", len.postfix_binary());
 
         ALLOC.memory.store(base, Ordering::SeqCst);
         *ALLOC.remaining.lock() = len;
     }
-    debug!("Usable system memory: {usable}");
+
+    debug!("Usable system memory: {}B", usable.postfix_binary());
 }
 
 //
diff --git a/src/smp.rs b/src/smp.rs
index c2bd0a62ce6ee1aed1656c96442dce3edde3389d..aa926d25285b23e6ca9bb9ee89f9d92b5dea4377 100644
--- a/src/smp.rs
+++ b/src/smp.rs
@@ -10,20 +10,12 @@ use core::fmt::{self, Display, Formatter};
 pub fn init() -> ! {
     debug!("Waking up non-boot CPUs");
     boot::smp_init();
-    smp_main(Cpu {
+    crate::smp_main(Cpu {
         processor_id: 0,
         local_apic_id: 0,
     })
 }
 
-pub fn smp_main(cpu: Cpu) -> ! {
-    debug!("Entering smp_main ({cpu})");
-
-    // x86_64::instructions::interrupts::int3();
-
-    arch::done();
-}
-
 //
 
 #[derive(Debug)]
diff --git a/src/util.rs b/src/util.rs
new file mode 100644
index 0000000000000000000000000000000000000000..e43b03aebf51bf8785494b31087b5f039b73760f
--- /dev/null
+++ b/src/util.rs
@@ -0,0 +1,86 @@
+use core::{fmt, ops::DivAssign};
+
+//
+
+pub trait NumberPostfix: Sized + Copy + DivAssign + PartialOrd {
+    const NUM_1000: Self;
+    const NUM_1024: Self;
+
+    fn postfix(mut self) -> NumberPostfixed<Self> {
+        const TABLE: [&'static str; 10] = ["", "K", "M", "G", "T", "P", "E", "Z", "Y", "R"];
+        for scale in TABLE {
+            if self < Self::NUM_1000 {
+                return NumberPostfixed { n: self, scale };
+            }
+            self /= Self::NUM_1000;
+        }
+        NumberPostfixed {
+            n: self,
+            scale: "Q",
+        }
+    }
+
+    fn postfix_binary(mut self) -> NumberPostfixed<Self> {
+        const TABLE: [&'static str; 10] =
+            ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", "Ri"];
+        for scale in TABLE {
+            if self < Self::NUM_1024 {
+                return NumberPostfixed { n: self, scale };
+            }
+            self /= Self::NUM_1024;
+        }
+        NumberPostfixed {
+            n: self,
+            scale: "Qi",
+        }
+    }
+}
+
+//
+
+#[derive(Debug)]
+pub struct NumberPostfixed<T> {
+    n: T,
+    scale: &'static str,
+}
+
+//
+
+impl NumberPostfix for f32 {
+    const NUM_1000: Self = 1000.0;
+    const NUM_1024: Self = 1024.0;
+}
+
+impl NumberPostfix for f64 {
+    const NUM_1000: Self = 1000.0;
+    const NUM_1024: Self = 1024.0;
+}
+
+impl NumberPostfix for u16 {
+    const NUM_1000: Self = 1000;
+    const NUM_1024: Self = 1024;
+}
+
+impl NumberPostfix for u32 {
+    const NUM_1000: Self = 1000;
+    const NUM_1024: Self = 1024;
+}
+
+impl NumberPostfix for u64 {
+    const NUM_1000: Self = 1000;
+    const NUM_1024: Self = 1024;
+}
+
+impl NumberPostfix for usize {
+    const NUM_1000: Self = 1000;
+    const NUM_1024: Self = 1024;
+}
+
+impl<T> fmt::Display for NumberPostfixed<T>
+where
+    T: fmt::Display,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{} {}", self.n, self.scale)
+    }
+}