From fdde40e10d795c0f5fd710e5d6ad0dbc1015089f Mon Sep 17 00:00:00 2001 From: juls0730 <62722391+juls0730@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:19:01 -0500 Subject: [PATCH] vscode tasks, better logging, and build numbering --- .vscode/launch.json | 16 +++++ .vscode/tasks.json | 25 ++++++++ Makefile | 10 +++- src/arch/x86_64/interrupts/apic.rs | 19 +++--- src/arch/x86_64/interrupts/exceptions.rs | 38 ++++++------ src/arch/x86_64/interrupts/mod.rs | 4 +- src/arch/x86_64/stack_trace.rs | 9 +-- src/drivers/acpi.rs | 15 +++-- src/drivers/fs/fat.rs | 9 +-- src/drivers/fs/initramfs/mod.rs | 5 +- src/drivers/fs/vfs.rs | 10 ++-- src/drivers/pci.rs | 5 +- src/drivers/storage/ide.rs | 30 +++++----- src/main.rs | 74 ++++++++++++++++-------- src/mem/mod.rs | 73 ++++++++++++++--------- 15 files changed, 230 insertions(+), 112 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e46201d --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "gdb", + "request": "attach", + "name": "Attach to QEMU", + "preLaunchTask": "(Debug) Build the kernel and run qemu", + "executable": "${workspaceFolder}/target/x86_64-unknown-none/debug/CappuccinOS.elf", + "target": ":1234", + "remote": true, + "cwd": "${workspaceRoot}", + // "gdbpath": "${workspaceRoot}/target/x86_64-unknown-none/debug/CappuccinOS.elf" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..ac76c1b --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,25 @@ +{ + "tasks": [ + { + "type": "shell", + "label": "(Debug) Build the kernel and run qemu", + "command": "make", + "args": [ + "run" + ], + "options": { + "env": { + "MODE": "debug", + "GDB": "true" + }, + "cwd": "${workspaceRoot}", + }, + "group": { + "kind": "build", + "isDefault": true + } + } + ], + "version": "2.0.0" + } + \ No newline at end of file diff --git a/Makefile b/Makefile index a8b4dbd..bd38fc2 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,8 @@ QEMU_OPTS += -m ${MEMORY} -drive id=hd0,format=raw,file=${IMAGE_PATH} LIMINE_BOOT_VARIATION = X64 LIMINE_BRANCH = v8.x-binary +KERNEL_FILE = target/${ARCH}-unknown-none/${MODE}/CappuccinOS.elf + ifeq (${MODE},release) CARGO_OPTS += --release endif @@ -87,8 +89,12 @@ compile-initramfs: copy-initramfs-files mksquashfs ${INITRAMFS_PATH} ${ARTIFACTS_PATH}/initramfs.img ${MKSQUASHFS_OPTS} run-scripts: + # Place the build ID into the binary so it can be read at runtime + @HASH=$$(md5sum ${KERNEL_FILE} | cut -c1-12) && \ + sed -i "s/__BUILD_ID__/$${HASH}/" ${KERNEL_FILE} + ifeq (${EXPORT_SYMBOLS},true) - nm target/${ARCH}-unknown-none/${MODE}/CappuccinOS.elf > scripts/symbols.table + nm ${KERNEL_FILE} > scripts/symbols.table @if [ ! -d "scripts/rustc_demangle" ]; then \ git clone "https://github.com/juls0730/rustc_demangle.py" "scripts/rustc_demangle"; \ fi @@ -190,7 +196,7 @@ ovmf-aarch64: run: build ${RUN_OPTS} run-${ARCH} run-x86_64: - qemu-system-x86_64 ${QEMU_OPTS} + tmux new-session -d -s qemu 'qemu-system-x86_64 ${QEMU_OPTS}' run-riscv64: qemu-system-riscv64 ${QEMU_OPTS} -cpu rv64 -device ramfb -device qemu-xhci -device usb-kbd -device virtio-scsi-pci,id=scsi -device scsi-hd,drive=hd0 diff --git a/src/arch/x86_64/interrupts/apic.rs b/src/arch/x86_64/interrupts/apic.rs index 1d4fdad..bd60c3e 100644 --- a/src/arch/x86_64/interrupts/apic.rs +++ b/src/arch/x86_64/interrupts/apic.rs @@ -1,4 +1,4 @@ -use crate::{drivers::acpi::SMP_REQUEST, hcf, libs::cell::OnceCell, mem::HHDM_OFFSET}; +use crate::{drivers::acpi::SMP_REQUEST, hcf, libs::cell::OnceCell, mem::HHDM_OFFSET, LogLevel}; use alloc::{sync::Arc, vec::Vec}; @@ -67,7 +67,7 @@ pub struct APIC { } unsafe extern "C" fn test<'a>(cpu: &'a limine::smp::Cpu) -> ! { - crate::log_ok!("hey from CPU {:<02}", cpu.id); + crate::log!(LogLevel::Debug, "hey from CPU {:<02}", cpu.id); hcf(); } @@ -94,7 +94,11 @@ impl APIC { let madt = madt.unwrap(); - crate::log_info!("MADT located at: {:p}", core::ptr::addr_of!(madt)); + crate::log!( + LogLevel::Trace, + "MADT located at: {:p}", + core::ptr::addr_of!(madt) + ); let mut lapic_ptr = (madt.inner.local_apic_address as usize + *HHDM_OFFSET) as *mut u8; let mut io_apic = None; @@ -149,7 +153,8 @@ impl APIC { let io_apic_ptr = io_apic.unwrap().ptr; - crate::println!( + crate::log!( + LogLevel::Debug, "Found {} core{}, IOAPIC {:p}, LAPIC {lapic_ptr:p}, Processor IDs:", cpus.len(), if cpus.len() > 1 { "s" } else { "" }, @@ -157,7 +162,7 @@ impl APIC { ); for apic in &cpus { - crate::println!(" {}", apic.acpi_processor_id); + crate::log!(LogLevel::Debug, " {}", apic.acpi_processor_id); } let apic = Self { @@ -171,9 +176,9 @@ impl APIC { let io_apic_ver = apic.read_ioapic(0x01); - let number_of_inputs = ((io_apic_ver >> 16) & 0xFF) + 1; + let _number_of_inputs = ((io_apic_ver >> 16) & 0xFF) + 1; - crate::println!("{number_of_inputs}"); + // crate::println!("{number_of_inputs}"); let smp_request = unsafe { SMP_REQUEST.get_response_mut() }; diff --git a/src/arch/x86_64/interrupts/exceptions.rs b/src/arch/x86_64/interrupts/exceptions.rs index 9c3f4d2..98714b0 100644 --- a/src/arch/x86_64/interrupts/exceptions.rs +++ b/src/arch/x86_64/interrupts/exceptions.rs @@ -1,8 +1,7 @@ use core::sync::atomic::{AtomicU8, Ordering}; use super::idt_set_gate; -use crate::hcf; -use crate::{log_error, log_info}; +use crate::{hcf, log, LogLevel}; #[repr(C)] #[derive(Clone, Copy, Debug)] @@ -43,7 +42,7 @@ extern "C" fn exception_handler(registers: u64) { match FAULTED.fetch_add(1, Ordering::SeqCst) { 0 => {} 1 => { - log_error!("Exception Loop detected, stopping here"); + log!(LogLevel::Fatal, "Exception Loop detected, stopping here"); print_registers(®isters); hcf(); } @@ -55,25 +54,25 @@ extern "C" fn exception_handler(registers: u64) { match int { 0x00 => { - log_error!("DIVISION ERROR!"); + log!(LogLevel::Fatal, "DIVISION ERROR!"); } 0x06 => { - log_error!("INVALID OPCODE!"); + log!(LogLevel::Fatal, "INVALID OPCODE!"); } 0x08 => { - log_error!("DOUBLE FAULT!"); + log!(LogLevel::Fatal, "DOUBLE FAULT!"); } 0x0D => { - log_error!("GENERAL PROTECTION FAULT!"); + log!(LogLevel::Fatal, "GENERAL PROTECTION FAULT!"); } 0x0E => { - log_error!("PAGE FAULT!"); + log!(LogLevel::Fatal, "PAGE FAULT!"); } 0xFF => { - log_error!("EXCEPTION!"); + log!(LogLevel::Fatal, "EXCEPTION!"); } _ => { - log_error!("EXCEPTION!"); + log!(LogLevel::Fatal, "EXCEPTION!"); } } @@ -83,9 +82,10 @@ extern "C" fn exception_handler(registers: u64) { } fn print_registers(registers: &Registers) { - log_info!("{:-^width$}", " REGISTERS ", width = 98); + log!(LogLevel::Info, "{:-^width$}", " REGISTERS ", width = 98); - log_info!( + log!( + LogLevel::Info, "INT: {:#018X}, RIP: {:#018X}, CS: {:#018X}, FLG: {:#018X}", registers.int, registers.rip, @@ -93,7 +93,8 @@ fn print_registers(registers: &Registers) { registers.rflags ); - log_info!( + log!( + LogLevel::Info, "RSP: {:#018X}, SS: {:#018X}, RAX: {:#018X}, RBX: {:#018X}", registers.rsp, registers.ss, @@ -101,7 +102,8 @@ fn print_registers(registers: &Registers) { registers.rbx ); - log_info!( + log!( + LogLevel::Info, "RCX: {:#018X}, RDX: {:#018X}, RSI: {:#018X}, RDI: {:#018X}", registers.rcx, registers.rdx, @@ -109,7 +111,8 @@ fn print_registers(registers: &Registers) { registers.rdi ); - log_info!( + log!( + LogLevel::Info, "RBP: {:#018X}, R8: {:#018X}, R9: {:#018X}, R10: {:#018X}", registers.rbp, registers.r8, @@ -117,7 +120,8 @@ fn print_registers(registers: &Registers) { registers.r10 ); - log_info!( + log!( + LogLevel::Info, "R11: {:#018X}, R12: {:#018X}, R13: {:#018X}, R14: {:#018X}", registers.r11, registers.r12, @@ -125,7 +129,7 @@ fn print_registers(registers: &Registers) { registers.r14 ); - log_info!("R15: {:#018X}", registers.r15); + log!(LogLevel::Info, "R15: {:#018X}", registers.r15); } // *macro intensifies* diff --git a/src/arch/x86_64/interrupts/mod.rs b/src/arch/x86_64/interrupts/mod.rs index 58fbd52..3c2807c 100755 --- a/src/arch/x86_64/interrupts/mod.rs +++ b/src/arch/x86_64/interrupts/mod.rs @@ -1,6 +1,8 @@ pub mod apic; pub mod exceptions; +use crate::LogLevel; + use self::apic::APIC; #[repr(C, packed)] @@ -78,7 +80,7 @@ pub fn idt_set_gate(num: u8, function_ptr: usize) { } extern "x86-interrupt" fn null_interrupt_handler() { - crate::log_info!("Unhandled interrupt!"); + crate::log!(LogLevel::Debug, "Unhandled interrupt!"); signal_end_of_interrupt(); } diff --git a/src/arch/x86_64/stack_trace.rs b/src/arch/x86_64/stack_trace.rs index f822fca..037b02e 100644 --- a/src/arch/x86_64/stack_trace.rs +++ b/src/arch/x86_64/stack_trace.rs @@ -2,8 +2,9 @@ use alloc::{borrow::ToOwned, string::String, vec::Vec}; use crate::{ drivers::fs::vfs::{vfs_open, UserCred}, - log_info, + log, mem::HHDM_OFFSET, + LogLevel, }; // use crate::drivers::fs::vfs::VfsFileSystem; @@ -19,7 +20,7 @@ pub fn print_stack_trace(max_frames: usize, rbp: u64) { let mut stackframe = rbp as *const StackFrame; let mut frames_processed = 0; - log_info!("{:-^width$}", " Stack Trace ", width = 98); + log!(LogLevel::Info, "{:-^width$}", " Stack Trace ", width = 98); for _ in 0..max_frames { frames_processed += 1; @@ -44,7 +45,7 @@ pub fn print_stack_trace(max_frames: usize, rbp: u64) { "" }; - log_info!("{:#X} {address_info}", instruction_ptr); + log!(LogLevel::Info, "{:#X} {address_info}", instruction_ptr); unsafe { stackframe = (*stackframe).back; @@ -52,7 +53,7 @@ pub fn print_stack_trace(max_frames: usize, rbp: u64) { } if frames_processed == max_frames && !stackframe.is_null() { - log_info!("... "); + log!(LogLevel::Info, "... "); } } diff --git a/src/drivers/acpi.rs b/src/drivers/acpi.rs index af415af..a9a4696 100644 --- a/src/drivers/acpi.rs +++ b/src/drivers/acpi.rs @@ -4,6 +4,7 @@ use alloc::vec::Vec; use limine::request::RsdpRequest; use limine::request::SmpRequest; +use crate::LogLevel; use crate::{ arch::io::{inw, outb}, libs::cell::OnceCell, @@ -45,7 +46,7 @@ impl<'a, T> SDT<'a, T> { let length = core::ptr::read_unaligned(ptr.add(4).cast::()); let data = core::slice::from_raw_parts(ptr, length as usize); - crate::log_serial!("SDT at: {ptr:p}\n"); + crate::log!(LogLevel::Trace, "SDT at: {ptr:p}"); assert!(data.len() == length as usize); @@ -267,11 +268,15 @@ struct FADT { pub fn init_acpi() { resolve_acpi(); - crate::log_ok!("Found {} ACPI Tables!", ACPI.tables.len()); + crate::log!(LogLevel::Trace, "Found {} ACPI Tables!", ACPI.tables.len()); - crate::log_serial!("Available serial tables:\n"); + crate::log!(LogLevel::Trace, "Available ACPI tables:"); for i in 0..ACPI.tables.len() { - crate::log_serial!(" {}\n", core::str::from_utf8(&ACPI.tables[i]).unwrap()); + crate::log!( + LogLevel::Trace, + " {}", + core::str::from_utf8(&ACPI.tables[i]).unwrap() + ); } let fadt = find_table::("FACP").expect("Failed to find FADT"); @@ -283,7 +288,7 @@ pub fn init_acpi() { #[cfg(target_arch = "x86_64")] crate::arch::interrupts::apic::APIC .set(crate::arch::interrupts::apic::APIC::new().expect("Failed to enable APIC!")); - crate::log_ok!("APIC enabled!"); + crate::log!(LogLevel::Trace, "APIC enabled!"); } pub fn find_table(table_name: &str) -> Option> { diff --git a/src/drivers/fs/fat.rs b/src/drivers/fs/fat.rs index 56b889e..885cbde 100755 --- a/src/drivers/fs/fat.rs +++ b/src/drivers/fs/fat.rs @@ -7,7 +7,7 @@ use alloc::{ vec::Vec, }; -use crate::drivers::storage::Partition; +use crate::{drivers::storage::Partition, LogLevel}; use super::vfs::{FsOps, VNode, VNodeOperations}; @@ -267,7 +267,7 @@ impl FatFs { _ => bpb.sectors_per_fat as usize, }; - crate::println!("Found {fat_type:?} FS"); + // crate::println!("Found {fat_type:?} FS"); let cluster_size = bpb.sectors_per_cluster as usize * 512; @@ -508,8 +508,9 @@ impl FsOps for FatFs { fat = Some(Arc::from(fat_vec)); } else { - crate::log_info!( - "\x1B[33mWARNING\x1B[0m: FAT is not being stored in memory, this feature is experimental and file reads are expected to be slower." + crate::log!( + LogLevel::Warn, + "FAT is not being stored in memory, this feature is experimental and file reads are expected to be slower." ) } diff --git a/src/drivers/fs/initramfs/mod.rs b/src/drivers/fs/initramfs/mod.rs index 0cee6a9..20ae5c4 100755 --- a/src/drivers/fs/initramfs/mod.rs +++ b/src/drivers/fs/initramfs/mod.rs @@ -336,7 +336,10 @@ impl Squashfs<'_> { ); } _ => { - crate::println!("Unsupported compression type") + crate::log!( + crate::LogLevel::Error, + "Unsupported squashfs compression type" + ) } } } else { diff --git a/src/drivers/fs/vfs.rs b/src/drivers/fs/vfs.rs index 4e426d4..a01162a 100755 --- a/src/drivers/fs/vfs.rs +++ b/src/drivers/fs/vfs.rs @@ -8,7 +8,7 @@ use alloc::{ vec::Vec, }; -use crate::{log_info, log_ok}; +use crate::{log, LogLevel}; static mut NODE_TREE: Option = None; static mut ROOT_VFS: Vfs = Vfs::null(); @@ -676,16 +676,14 @@ pub fn add_vfs(mount_point: &str, fs_ops: Box) -> Result<(), ()> { let vfsp = vfs.as_ptr(); - log_info!("Adding vfs at {mount_point}"); + log!(LogLevel::Trace, "Adding vfs at {mount_point}"); if mount_point == "/" { if unsafe { ROOT_VFS.next.is_some() } { return Err(()); } - crate::println!("reading the root"); let root = vfs.fs.as_mut().unwrap().as_mut().root(vfsp); - crate::println!("successfully read the root"); unsafe { NODE_TREE = Some(TreeNode::new(root)) } } else { if unsafe { ROOT_VFS.next.is_none() } { @@ -705,7 +703,7 @@ pub fn add_vfs(mount_point: &str, fs_ops: Box) -> Result<(), ()> { unsafe { ROOT_VFS.add_vfs(vfs) }; - log_ok!("Added vfs at {mount_point}"); + log!(LogLevel::Trace, "Added vfs at {mount_point}"); return Ok(()); } @@ -756,7 +754,7 @@ pub fn del_vfs(mount_point: &str) -> Result<(), ()> { return Err(()); } - log_info!("Deleting vfs at {mount_point}"); + log!(LogLevel::Trace, "Deleting vfs at {mount_point}"); if mount_point == "/" { if unsafe { ROOT_VFS.next.as_ref().unwrap().next.is_some() } { diff --git a/src/drivers/pci.rs b/src/drivers/pci.rs index 834dd62..549acdb 100755 --- a/src/drivers/pci.rs +++ b/src/drivers/pci.rs @@ -3,6 +3,7 @@ use alloc::vec::Vec; use crate::{ arch::io::{inl, outl}, libs::sync::Mutex, + LogLevel, }; const PCI_CONFIG_PORT: u16 = 0xCF8; // The base I/O port for PCI configuration access @@ -130,9 +131,9 @@ pub fn enumerate_pci_bus() { check_bus(bus); } - crate::println!("====== PCI DEVICES ======"); + crate::log!(LogLevel::Debug, "====== PCI DEVICES ======"); for (i, pci_device) in PCI_DEVICES.lock().iter().enumerate() { - crate::println!("Entry {i:2}: {pci_device}") + crate::log!(LogLevel::Debug, "Entry {i:2}: {pci_device}") } } diff --git a/src/drivers/storage/ide.rs b/src/drivers/storage/ide.rs index 5605dfe..11252e3 100755 --- a/src/drivers/storage/ide.rs +++ b/src/drivers/storage/ide.rs @@ -9,6 +9,8 @@ use crate::{ storage::{GPTHeader, GPTPartitionEntry, Partition, MBR}, }, libs::{sync::Mutex, uuid::Uuid}, + mem::LabelBytes, + LogLevel, }; use super::BlockDevice; @@ -278,7 +280,7 @@ impl ATABus { let mut buffer = [0u8; ATA_SECTOR_SIZE]; self.wait_for_drive_ready() - .map_err(|_| crate::log_error!("Error before issuing Identify command."))?; + .map_err(|_| crate::log!(LogLevel::Error, "Error before issuing Identify command."))?; for chunk in buffer.chunks_exact_mut(core::mem::size_of::()) { let word = inw(self.io_bar + ATADriveDataRegister::Data as u16); @@ -423,7 +425,7 @@ impl ATABus { let mut buffer_offset = 0; for _ in 0..sector_count { self.wait_for_drive_ready() - .map_err(|_| crate::log_error!("Error reading IDE Device"))?; + .map_err(|_| crate::log!(LogLevel::Error, "Error reading IDE Device"))?; // # Safety // @@ -563,7 +565,8 @@ fn ide_initialize(bar0: u32, bar1: u32, _bar2: u32, _bar3: u32, _bar4: u32) { } } - crate::log_info!( + crate::log!( + LogLevel::Trace, "ATA: Detected {} drive{}", drives_lock.len(), match drives_lock.len() { @@ -575,10 +578,11 @@ fn ide_initialize(bar0: u32, bar1: u32, _bar2: u32, _bar3: u32, _bar4: u32) { for drive in drives_lock.iter() { let sectors = drive.sector_count(); - crate::log_info!( - "ATA: Drive 0 has {} sectors ({} MB)", + crate::log!( + LogLevel::Trace, + "ATA: Drive 0 has {} sectors ({})", sectors, - (sectors * ATA_SECTOR_SIZE as u64) / 1024 / 1024 + ((sectors as usize) * ATA_SECTOR_SIZE).label_bytes() ); let mbr_sector: MBR = (*drive.read(0, 1).expect("Failed to read first sector")).into(); @@ -609,13 +613,13 @@ fn ide_initialize(bar0: u32, bar1: u32, _bar2: u32, _bar3: u32, _bar4: u32) { ) .expect("Failed to read partition table"); - crate::println!( - "{}, {}, {}, {:X?}", - (gpt.partition_entry_count * gpt.partition_entry_size) as usize / ATA_SECTOR_SIZE, - gpt.partition_entry_count, - gpt.partition_entry_size, - gpt.guid - ); + // crate::println!( + // "{}, {}, {}, {:X?}", + // (gpt.partition_entry_count * gpt.partition_entry_size) as usize / ATA_SECTOR_SIZE, + // gpt.partition_entry_count, + // gpt.partition_entry_size, + // gpt.guid + // ); for i in 0..gpt.partition_entry_count { let entry_offset = (i * gpt.partition_entry_size) as usize; diff --git a/src/main.rs b/src/main.rs index 6dc28a6..f7e7368 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ use alloc::vec::Vec; use limine::{request::KernelFileRequest, BaseRevision}; -use mem::HHDM_OFFSET; +use mem::{LabelBytes, HHDM_OFFSET, PHYSICAL_MEMORY_MANAGER}; use crate::drivers::fs::{ initramfs, @@ -19,6 +19,11 @@ pub mod drivers; pub mod libs; pub mod mem; +// the build id will be an md5sum of the kernel binary and will replace __BUILD_ID__ in the final binary +pub static BUILD_ID: &str = "__BUILD_ID__"; + +pub static LOG_LEVEL: u8 = if cfg!(debug_assertions) { 1 } else { 2 }; + // Be sure to mark all limine requests with #[used], otherwise they may be removed by the compiler. #[used] // The .requests section allows limine to find the requests faster and more safely. @@ -47,6 +52,8 @@ pub extern "C" fn _start() -> ! { } pub fn kmain() -> ! { + print_boot_info(); + let _ = drivers::fs::vfs::add_vfs("/", alloc::boxed::Box::new(initramfs::init())); #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] @@ -102,10 +109,6 @@ pub fn kmain() -> ! { .read(0, 0, 0) ); - unsafe { - *(0xDEADBEEF as *mut u32) = 0xBAADF00D; - }; - // let file = vfs_open("/example.txt").unwrap(); // as a sign that we didnt panic @@ -163,6 +166,26 @@ fn draw_gradient() { .dealloc((buffer_ptr as usize - *HHDM_OFFSET) as *mut u8, pages); } +fn print_boot_info() { + crate::println!("╔═╗───────────────────╔╗────╔═╗╔══╗"); + crate::println!("║╔╝╔═╗ ╔═╗╔═╗╔╦╗╔═╗╔═╗╠╣╔═╦╗║║║║══╣"); + crate::println!("║╚╗║╬╚╗║╬║║╬║║║║║═╣║═╣║║║║║║║║║╠══║"); + crate::println!("╚═╝╚══╝║╔╝║╔╝╚═╝╚═╝╚═╝╚╝╚╩═╝╚═╝╚══╝"); + crate::println!("───────╚╝─╚╝ ©juls0730 {BUILD_ID}"); + crate::println!( + "{} of memory available", + PHYSICAL_MEMORY_MANAGER.total_memory().label_bytes() + ); + crate::println!( + "The kernel was built in {} mode", + if cfg!(debug_assertions) { + "debug" + } else { + "release" + } + ) +} + #[macro_export] macro_rules! println { () => ($crate::print!("\n")); @@ -176,26 +199,31 @@ macro_rules! print { ) } -#[macro_export] -macro_rules! log_info { - ($($arg:tt)*) => ($crate::println!("\x1B[97m[ \x1B[90m? \x1B[97m]\x1B[0m {}", &alloc::format!($($arg)*))); +#[repr(u8)] +enum LogLevel { + Trace = 0, + Debug, + Info, + Warn, + Error, + Fatal, } #[macro_export] -macro_rules! log_serial { - ($($arg:tt)*) => ( - $crate::drivers::serial::write_string(&alloc::format!($($arg)*).replace('\n', "\n\r")) - ); -} - -#[macro_export] -macro_rules! log_error { - ($($arg:tt)*) => ($crate::println!("\x1B[97m[ \x1B[91m! \x1B[97m]\x1B[0m {}", &alloc::format!($($arg)*))); -} - -#[macro_export] -macro_rules! log_ok { - ($($arg:tt)*) => ($crate::println!("\x1B[97m[ \x1B[92m* \x1B[97m]\x1B[0;m {}", &alloc::format!($($arg)*))); +macro_rules! log { + ($level:expr, $($arg:tt)*) => {{ + if ($level as u8) >= $crate::LOG_LEVEL { + let color_code = match $level { + $crate::LogLevel::Trace => "\x1B[90m", + $crate::LogLevel::Debug => "\x1B[94m", + $crate::LogLevel::Info => "\x1B[92m", + $crate::LogLevel::Warn => "\x1B[93m", + $crate::LogLevel::Error => "\x1B[91m", + $crate::LogLevel::Fatal => "\x1B[95m", + }; + $crate::println!("\x1B[97m[ {}* \x1B[97m]\x1B[0;m {}", color_code, &alloc::format!($($arg)*)) + } + }}; } #[derive(Debug)] @@ -229,7 +257,7 @@ fn parse_kernel_cmdline() { let kernel_arguments = cmdline.unwrap().split_whitespace().collect::>(); - crate::println!("{kernel_arguments:?}"); + // crate::log!(LogLevel::Trace, "{kernel_arguments:?}"); for item in kernel_arguments { let parts: Vec<&str> = item.split('=').collect(); diff --git a/src/mem/mod.rs b/src/mem/mod.rs index 57f7d80..0101cad 100755 --- a/src/mem/mod.rs +++ b/src/mem/mod.rs @@ -55,56 +55,75 @@ pub fn init_allocator() { drop(allocator_lock); - crate::println!( - "{} of memory available", - PHYSICAL_MEMORY_MANAGER.total_memory().label_bytes() - ); - // log_memory_map(); } -pub enum Label { - BYTE(usize), - KIB(usize), - MIB(usize), - GIB(usize), +pub enum ByteLabelKind { + BYTE, + KIB, + MIB, + GIB, } -impl core::fmt::Display for Label { +pub struct ByteLabel { + byte_label: ByteLabelKind, + count: usize, +} + +impl core::fmt::Display for ByteLabel { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - Label::BYTE(count) => { - write!(f, "{count} Byte(s)") + let size = self.count; + + match self.byte_label { + ByteLabelKind::BYTE => { + write!(f, "{size} Byte")?; } - Label::KIB(count) => { - write!(f, "{count} KiB(s)") + ByteLabelKind::KIB => { + write!(f, "{size} KiB")?; } - Label::MIB(count) => { - write!(f, "{count} MiB(s)") + ByteLabelKind::MIB => { + write!(f, "{size} MiB")?; } - Label::GIB(count) => { - write!(f, "{count} GiB(s)") + ByteLabelKind::GIB => { + write!(f, "{size} GiB")?; } } + + if size != 1 { + write!(f, "s")?; + } + + return Ok(()); } } pub trait LabelBytes { - fn label_bytes(&self) -> Label; + fn label_bytes(&self) -> ByteLabel; } impl LabelBytes for usize { - fn label_bytes(&self) -> Label { + fn label_bytes(&self) -> ByteLabel { let bytes = *self; + let mut byte_label = ByteLabel { + byte_label: ByteLabelKind::BYTE, + count: bytes, + }; + if bytes >> 30 > 0 { - return Label::GIB(bytes >> 30); + byte_label.byte_label = ByteLabelKind::GIB; + byte_label.count = bytes >> 30; + // return Label::GIB(bytes >> 30); } else if bytes >> 20 > 0 { - return Label::MIB(bytes >> 20); + byte_label.byte_label = ByteLabelKind::MIB; + byte_label.count = bytes >> 20; + // return Label::MIB(bytes >> 20); } else if bytes >> 10 > 0 { - return Label::KIB(bytes >> 10); - } else { - return Label::BYTE(bytes); + byte_label.byte_label = ByteLabelKind::KIB; + byte_label.count = bytes >> 10; + // return Label::KIB(bytes >> 10); } + + return byte_label; } }