vscode tasks, better logging, and build numbering
This commit is contained in:
16
.vscode/launch.json
vendored
Normal file
16
.vscode/launch.json
vendored
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
25
.vscode/tasks.json
vendored
Normal file
25
.vscode/tasks.json
vendored
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
|
||||||
10
Makefile
10
Makefile
@@ -22,6 +22,8 @@ QEMU_OPTS += -m ${MEMORY} -drive id=hd0,format=raw,file=${IMAGE_PATH}
|
|||||||
LIMINE_BOOT_VARIATION = X64
|
LIMINE_BOOT_VARIATION = X64
|
||||||
LIMINE_BRANCH = v8.x-binary
|
LIMINE_BRANCH = v8.x-binary
|
||||||
|
|
||||||
|
KERNEL_FILE = target/${ARCH}-unknown-none/${MODE}/CappuccinOS.elf
|
||||||
|
|
||||||
ifeq (${MODE},release)
|
ifeq (${MODE},release)
|
||||||
CARGO_OPTS += --release
|
CARGO_OPTS += --release
|
||||||
endif
|
endif
|
||||||
@@ -87,8 +89,12 @@ compile-initramfs: copy-initramfs-files
|
|||||||
mksquashfs ${INITRAMFS_PATH} ${ARTIFACTS_PATH}/initramfs.img ${MKSQUASHFS_OPTS}
|
mksquashfs ${INITRAMFS_PATH} ${ARTIFACTS_PATH}/initramfs.img ${MKSQUASHFS_OPTS}
|
||||||
|
|
||||||
run-scripts:
|
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)
|
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 \
|
@if [ ! -d "scripts/rustc_demangle" ]; then \
|
||||||
git clone "https://github.com/juls0730/rustc_demangle.py" "scripts/rustc_demangle"; \
|
git clone "https://github.com/juls0730/rustc_demangle.py" "scripts/rustc_demangle"; \
|
||||||
fi
|
fi
|
||||||
@@ -190,7 +196,7 @@ ovmf-aarch64:
|
|||||||
run: build ${RUN_OPTS} run-${ARCH}
|
run: build ${RUN_OPTS} run-${ARCH}
|
||||||
|
|
||||||
run-x86_64:
|
run-x86_64:
|
||||||
qemu-system-x86_64 ${QEMU_OPTS}
|
tmux new-session -d -s qemu 'qemu-system-x86_64 ${QEMU_OPTS}'
|
||||||
|
|
||||||
run-riscv64:
|
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
|
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
|
||||||
|
|||||||
@@ -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};
|
use alloc::{sync::Arc, vec::Vec};
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ pub struct APIC {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn test<'a>(cpu: &'a limine::smp::Cpu) -> ! {
|
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();
|
hcf();
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,11 @@ impl APIC {
|
|||||||
|
|
||||||
let madt = madt.unwrap();
|
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 lapic_ptr = (madt.inner.local_apic_address as usize + *HHDM_OFFSET) as *mut u8;
|
||||||
let mut io_apic = None;
|
let mut io_apic = None;
|
||||||
@@ -149,7 +153,8 @@ impl APIC {
|
|||||||
|
|
||||||
let io_apic_ptr = io_apic.unwrap().ptr;
|
let io_apic_ptr = io_apic.unwrap().ptr;
|
||||||
|
|
||||||
crate::println!(
|
crate::log!(
|
||||||
|
LogLevel::Debug,
|
||||||
"Found {} core{}, IOAPIC {:p}, LAPIC {lapic_ptr:p}, Processor IDs:",
|
"Found {} core{}, IOAPIC {:p}, LAPIC {lapic_ptr:p}, Processor IDs:",
|
||||||
cpus.len(),
|
cpus.len(),
|
||||||
if cpus.len() > 1 { "s" } else { "" },
|
if cpus.len() > 1 { "s" } else { "" },
|
||||||
@@ -157,7 +162,7 @@ impl APIC {
|
|||||||
);
|
);
|
||||||
|
|
||||||
for apic in &cpus {
|
for apic in &cpus {
|
||||||
crate::println!(" {}", apic.acpi_processor_id);
|
crate::log!(LogLevel::Debug, " {}", apic.acpi_processor_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
let apic = Self {
|
let apic = Self {
|
||||||
@@ -171,9 +176,9 @@ impl APIC {
|
|||||||
|
|
||||||
let io_apic_ver = apic.read_ioapic(0x01);
|
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() };
|
let smp_request = unsafe { SMP_REQUEST.get_response_mut() };
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
use core::sync::atomic::{AtomicU8, Ordering};
|
use core::sync::atomic::{AtomicU8, Ordering};
|
||||||
|
|
||||||
use super::idt_set_gate;
|
use super::idt_set_gate;
|
||||||
use crate::hcf;
|
use crate::{hcf, log, LogLevel};
|
||||||
use crate::{log_error, log_info};
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
@@ -43,7 +42,7 @@ extern "C" fn exception_handler(registers: u64) {
|
|||||||
match FAULTED.fetch_add(1, Ordering::SeqCst) {
|
match FAULTED.fetch_add(1, Ordering::SeqCst) {
|
||||||
0 => {}
|
0 => {}
|
||||||
1 => {
|
1 => {
|
||||||
log_error!("Exception Loop detected, stopping here");
|
log!(LogLevel::Fatal, "Exception Loop detected, stopping here");
|
||||||
print_registers(®isters);
|
print_registers(®isters);
|
||||||
hcf();
|
hcf();
|
||||||
}
|
}
|
||||||
@@ -55,25 +54,25 @@ extern "C" fn exception_handler(registers: u64) {
|
|||||||
|
|
||||||
match int {
|
match int {
|
||||||
0x00 => {
|
0x00 => {
|
||||||
log_error!("DIVISION ERROR!");
|
log!(LogLevel::Fatal, "DIVISION ERROR!");
|
||||||
}
|
}
|
||||||
0x06 => {
|
0x06 => {
|
||||||
log_error!("INVALID OPCODE!");
|
log!(LogLevel::Fatal, "INVALID OPCODE!");
|
||||||
}
|
}
|
||||||
0x08 => {
|
0x08 => {
|
||||||
log_error!("DOUBLE FAULT!");
|
log!(LogLevel::Fatal, "DOUBLE FAULT!");
|
||||||
}
|
}
|
||||||
0x0D => {
|
0x0D => {
|
||||||
log_error!("GENERAL PROTECTION FAULT!");
|
log!(LogLevel::Fatal, "GENERAL PROTECTION FAULT!");
|
||||||
}
|
}
|
||||||
0x0E => {
|
0x0E => {
|
||||||
log_error!("PAGE FAULT!");
|
log!(LogLevel::Fatal, "PAGE FAULT!");
|
||||||
}
|
}
|
||||||
0xFF => {
|
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) {
|
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}",
|
"INT: {:#018X}, RIP: {:#018X}, CS: {:#018X}, FLG: {:#018X}",
|
||||||
registers.int,
|
registers.int,
|
||||||
registers.rip,
|
registers.rip,
|
||||||
@@ -93,7 +93,8 @@ fn print_registers(registers: &Registers) {
|
|||||||
registers.rflags
|
registers.rflags
|
||||||
);
|
);
|
||||||
|
|
||||||
log_info!(
|
log!(
|
||||||
|
LogLevel::Info,
|
||||||
"RSP: {:#018X}, SS: {:#018X}, RAX: {:#018X}, RBX: {:#018X}",
|
"RSP: {:#018X}, SS: {:#018X}, RAX: {:#018X}, RBX: {:#018X}",
|
||||||
registers.rsp,
|
registers.rsp,
|
||||||
registers.ss,
|
registers.ss,
|
||||||
@@ -101,7 +102,8 @@ fn print_registers(registers: &Registers) {
|
|||||||
registers.rbx
|
registers.rbx
|
||||||
);
|
);
|
||||||
|
|
||||||
log_info!(
|
log!(
|
||||||
|
LogLevel::Info,
|
||||||
"RCX: {:#018X}, RDX: {:#018X}, RSI: {:#018X}, RDI: {:#018X}",
|
"RCX: {:#018X}, RDX: {:#018X}, RSI: {:#018X}, RDI: {:#018X}",
|
||||||
registers.rcx,
|
registers.rcx,
|
||||||
registers.rdx,
|
registers.rdx,
|
||||||
@@ -109,7 +111,8 @@ fn print_registers(registers: &Registers) {
|
|||||||
registers.rdi
|
registers.rdi
|
||||||
);
|
);
|
||||||
|
|
||||||
log_info!(
|
log!(
|
||||||
|
LogLevel::Info,
|
||||||
"RBP: {:#018X}, R8: {:#018X}, R9: {:#018X}, R10: {:#018X}",
|
"RBP: {:#018X}, R8: {:#018X}, R9: {:#018X}, R10: {:#018X}",
|
||||||
registers.rbp,
|
registers.rbp,
|
||||||
registers.r8,
|
registers.r8,
|
||||||
@@ -117,7 +120,8 @@ fn print_registers(registers: &Registers) {
|
|||||||
registers.r10
|
registers.r10
|
||||||
);
|
);
|
||||||
|
|
||||||
log_info!(
|
log!(
|
||||||
|
LogLevel::Info,
|
||||||
"R11: {:#018X}, R12: {:#018X}, R13: {:#018X}, R14: {:#018X}",
|
"R11: {:#018X}, R12: {:#018X}, R13: {:#018X}, R14: {:#018X}",
|
||||||
registers.r11,
|
registers.r11,
|
||||||
registers.r12,
|
registers.r12,
|
||||||
@@ -125,7 +129,7 @@ fn print_registers(registers: &Registers) {
|
|||||||
registers.r14
|
registers.r14
|
||||||
);
|
);
|
||||||
|
|
||||||
log_info!("R15: {:#018X}", registers.r15);
|
log!(LogLevel::Info, "R15: {:#018X}", registers.r15);
|
||||||
}
|
}
|
||||||
|
|
||||||
// *macro intensifies*
|
// *macro intensifies*
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
pub mod apic;
|
pub mod apic;
|
||||||
pub mod exceptions;
|
pub mod exceptions;
|
||||||
|
|
||||||
|
use crate::LogLevel;
|
||||||
|
|
||||||
use self::apic::APIC;
|
use self::apic::APIC;
|
||||||
|
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
@@ -78,7 +80,7 @@ pub fn idt_set_gate(num: u8, function_ptr: usize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "x86-interrupt" fn null_interrupt_handler() {
|
extern "x86-interrupt" fn null_interrupt_handler() {
|
||||||
crate::log_info!("Unhandled interrupt!");
|
crate::log!(LogLevel::Debug, "Unhandled interrupt!");
|
||||||
signal_end_of_interrupt();
|
signal_end_of_interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ use alloc::{borrow::ToOwned, string::String, vec::Vec};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
drivers::fs::vfs::{vfs_open, UserCred},
|
drivers::fs::vfs::{vfs_open, UserCred},
|
||||||
log_info,
|
log,
|
||||||
mem::HHDM_OFFSET,
|
mem::HHDM_OFFSET,
|
||||||
|
LogLevel,
|
||||||
};
|
};
|
||||||
|
|
||||||
// use crate::drivers::fs::vfs::VfsFileSystem;
|
// 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 stackframe = rbp as *const StackFrame;
|
||||||
let mut frames_processed = 0;
|
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 {
|
for _ in 0..max_frames {
|
||||||
frames_processed += 1;
|
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 {
|
unsafe {
|
||||||
stackframe = (*stackframe).back;
|
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() {
|
if frames_processed == max_frames && !stackframe.is_null() {
|
||||||
log_info!("... <frames omitted>");
|
log!(LogLevel::Info, "... <frames omitted>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use alloc::vec::Vec;
|
|||||||
use limine::request::RsdpRequest;
|
use limine::request::RsdpRequest;
|
||||||
use limine::request::SmpRequest;
|
use limine::request::SmpRequest;
|
||||||
|
|
||||||
|
use crate::LogLevel;
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::io::{inw, outb},
|
arch::io::{inw, outb},
|
||||||
libs::cell::OnceCell,
|
libs::cell::OnceCell,
|
||||||
@@ -45,7 +46,7 @@ impl<'a, T> SDT<'a, T> {
|
|||||||
let length = core::ptr::read_unaligned(ptr.add(4).cast::<u32>());
|
let length = core::ptr::read_unaligned(ptr.add(4).cast::<u32>());
|
||||||
let data = core::slice::from_raw_parts(ptr, length as usize);
|
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);
|
assert!(data.len() == length as usize);
|
||||||
|
|
||||||
@@ -267,11 +268,15 @@ struct FADT {
|
|||||||
pub fn init_acpi() {
|
pub fn init_acpi() {
|
||||||
resolve_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() {
|
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::<FADT>("FACP").expect("Failed to find FADT");
|
let fadt = find_table::<FADT>("FACP").expect("Failed to find FADT");
|
||||||
@@ -283,7 +288,7 @@ pub fn init_acpi() {
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
crate::arch::interrupts::apic::APIC
|
crate::arch::interrupts::apic::APIC
|
||||||
.set(crate::arch::interrupts::apic::APIC::new().expect("Failed to enable 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<T>(table_name: &str) -> Option<SDT<T>> {
|
pub fn find_table<T>(table_name: &str) -> Option<SDT<T>> {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use alloc::{
|
|||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::drivers::storage::Partition;
|
use crate::{drivers::storage::Partition, LogLevel};
|
||||||
|
|
||||||
use super::vfs::{FsOps, VNode, VNodeOperations};
|
use super::vfs::{FsOps, VNode, VNodeOperations};
|
||||||
|
|
||||||
@@ -267,7 +267,7 @@ impl FatFs {
|
|||||||
_ => bpb.sectors_per_fat as usize,
|
_ => 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;
|
let cluster_size = bpb.sectors_per_cluster as usize * 512;
|
||||||
|
|
||||||
@@ -508,8 +508,9 @@ impl FsOps for FatFs {
|
|||||||
|
|
||||||
fat = Some(Arc::from(fat_vec));
|
fat = Some(Arc::from(fat_vec));
|
||||||
} else {
|
} else {
|
||||||
crate::log_info!(
|
crate::log!(
|
||||||
"\x1B[33mWARNING\x1B[0m: FAT is not being stored in memory, this feature is experimental and file reads are expected to be slower."
|
LogLevel::Warn,
|
||||||
|
"FAT is not being stored in memory, this feature is experimental and file reads are expected to be slower."
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -336,7 +336,10 @@ impl Squashfs<'_> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
crate::println!("Unsupported compression type")
|
crate::log!(
|
||||||
|
crate::LogLevel::Error,
|
||||||
|
"Unsupported squashfs compression type"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use alloc::{
|
|||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{log_info, log_ok};
|
use crate::{log, LogLevel};
|
||||||
|
|
||||||
static mut NODE_TREE: Option<TreeNode> = None;
|
static mut NODE_TREE: Option<TreeNode> = None;
|
||||||
static mut ROOT_VFS: Vfs = Vfs::null();
|
static mut ROOT_VFS: Vfs = Vfs::null();
|
||||||
@@ -676,16 +676,14 @@ pub fn add_vfs(mount_point: &str, fs_ops: Box<dyn FsOps>) -> Result<(), ()> {
|
|||||||
|
|
||||||
let vfsp = vfs.as_ptr();
|
let vfsp = vfs.as_ptr();
|
||||||
|
|
||||||
log_info!("Adding vfs at {mount_point}");
|
log!(LogLevel::Trace, "Adding vfs at {mount_point}");
|
||||||
|
|
||||||
if mount_point == "/" {
|
if mount_point == "/" {
|
||||||
if unsafe { ROOT_VFS.next.is_some() } {
|
if unsafe { ROOT_VFS.next.is_some() } {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::println!("reading the root");
|
|
||||||
let root = vfs.fs.as_mut().unwrap().as_mut().root(vfsp);
|
let root = vfs.fs.as_mut().unwrap().as_mut().root(vfsp);
|
||||||
crate::println!("successfully read the root");
|
|
||||||
unsafe { NODE_TREE = Some(TreeNode::new(root)) }
|
unsafe { NODE_TREE = Some(TreeNode::new(root)) }
|
||||||
} else {
|
} else {
|
||||||
if unsafe { ROOT_VFS.next.is_none() } {
|
if unsafe { ROOT_VFS.next.is_none() } {
|
||||||
@@ -705,7 +703,7 @@ pub fn add_vfs(mount_point: &str, fs_ops: Box<dyn FsOps>) -> Result<(), ()> {
|
|||||||
|
|
||||||
unsafe { ROOT_VFS.add_vfs(vfs) };
|
unsafe { ROOT_VFS.add_vfs(vfs) };
|
||||||
|
|
||||||
log_ok!("Added vfs at {mount_point}");
|
log!(LogLevel::Trace, "Added vfs at {mount_point}");
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@@ -756,7 +754,7 @@ pub fn del_vfs(mount_point: &str) -> Result<(), ()> {
|
|||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info!("Deleting vfs at {mount_point}");
|
log!(LogLevel::Trace, "Deleting vfs at {mount_point}");
|
||||||
|
|
||||||
if mount_point == "/" {
|
if mount_point == "/" {
|
||||||
if unsafe { ROOT_VFS.next.as_ref().unwrap().next.is_some() } {
|
if unsafe { ROOT_VFS.next.as_ref().unwrap().next.is_some() } {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use alloc::vec::Vec;
|
|||||||
use crate::{
|
use crate::{
|
||||||
arch::io::{inl, outl},
|
arch::io::{inl, outl},
|
||||||
libs::sync::Mutex,
|
libs::sync::Mutex,
|
||||||
|
LogLevel,
|
||||||
};
|
};
|
||||||
|
|
||||||
const PCI_CONFIG_PORT: u16 = 0xCF8; // The base I/O port for PCI configuration access
|
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);
|
check_bus(bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::println!("====== PCI DEVICES ======");
|
crate::log!(LogLevel::Debug, "====== PCI DEVICES ======");
|
||||||
for (i, pci_device) in PCI_DEVICES.lock().iter().enumerate() {
|
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}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ use crate::{
|
|||||||
storage::{GPTHeader, GPTPartitionEntry, Partition, MBR},
|
storage::{GPTHeader, GPTPartitionEntry, Partition, MBR},
|
||||||
},
|
},
|
||||||
libs::{sync::Mutex, uuid::Uuid},
|
libs::{sync::Mutex, uuid::Uuid},
|
||||||
|
mem::LabelBytes,
|
||||||
|
LogLevel,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::BlockDevice;
|
use super::BlockDevice;
|
||||||
@@ -278,7 +280,7 @@ impl ATABus {
|
|||||||
let mut buffer = [0u8; ATA_SECTOR_SIZE];
|
let mut buffer = [0u8; ATA_SECTOR_SIZE];
|
||||||
|
|
||||||
self.wait_for_drive_ready()
|
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::<u16>()) {
|
for chunk in buffer.chunks_exact_mut(core::mem::size_of::<u16>()) {
|
||||||
let word = inw(self.io_bar + ATADriveDataRegister::Data as u16);
|
let word = inw(self.io_bar + ATADriveDataRegister::Data as u16);
|
||||||
@@ -423,7 +425,7 @@ impl ATABus {
|
|||||||
let mut buffer_offset = 0;
|
let mut buffer_offset = 0;
|
||||||
for _ in 0..sector_count {
|
for _ in 0..sector_count {
|
||||||
self.wait_for_drive_ready()
|
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
|
// # 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{}",
|
"ATA: Detected {} drive{}",
|
||||||
drives_lock.len(),
|
drives_lock.len(),
|
||||||
match 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() {
|
for drive in drives_lock.iter() {
|
||||||
let sectors = drive.sector_count();
|
let sectors = drive.sector_count();
|
||||||
|
|
||||||
crate::log_info!(
|
crate::log!(
|
||||||
"ATA: Drive 0 has {} sectors ({} MB)",
|
LogLevel::Trace,
|
||||||
|
"ATA: Drive 0 has {} sectors ({})",
|
||||||
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();
|
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");
|
.expect("Failed to read partition table");
|
||||||
|
|
||||||
crate::println!(
|
// crate::println!(
|
||||||
"{}, {}, {}, {:X?}",
|
// "{}, {}, {}, {:X?}",
|
||||||
(gpt.partition_entry_count * gpt.partition_entry_size) as usize / ATA_SECTOR_SIZE,
|
// (gpt.partition_entry_count * gpt.partition_entry_size) as usize / ATA_SECTOR_SIZE,
|
||||||
gpt.partition_entry_count,
|
// gpt.partition_entry_count,
|
||||||
gpt.partition_entry_size,
|
// gpt.partition_entry_size,
|
||||||
gpt.guid
|
// gpt.guid
|
||||||
);
|
// );
|
||||||
|
|
||||||
for i in 0..gpt.partition_entry_count {
|
for i in 0..gpt.partition_entry_count {
|
||||||
let entry_offset = (i * gpt.partition_entry_size) as usize;
|
let entry_offset = (i * gpt.partition_entry_size) as usize;
|
||||||
|
|||||||
74
src/main.rs
74
src/main.rs
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use limine::{request::KernelFileRequest, BaseRevision};
|
use limine::{request::KernelFileRequest, BaseRevision};
|
||||||
use mem::HHDM_OFFSET;
|
use mem::{LabelBytes, HHDM_OFFSET, PHYSICAL_MEMORY_MANAGER};
|
||||||
|
|
||||||
use crate::drivers::fs::{
|
use crate::drivers::fs::{
|
||||||
initramfs,
|
initramfs,
|
||||||
@@ -19,6 +19,11 @@ pub mod drivers;
|
|||||||
pub mod libs;
|
pub mod libs;
|
||||||
pub mod mem;
|
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.
|
// Be sure to mark all limine requests with #[used], otherwise they may be removed by the compiler.
|
||||||
#[used]
|
#[used]
|
||||||
// The .requests section allows limine to find the requests faster and more safely.
|
// 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() -> ! {
|
pub fn kmain() -> ! {
|
||||||
|
print_boot_info();
|
||||||
|
|
||||||
let _ = drivers::fs::vfs::add_vfs("/", alloc::boxed::Box::new(initramfs::init()));
|
let _ = drivers::fs::vfs::add_vfs("/", alloc::boxed::Box::new(initramfs::init()));
|
||||||
|
|
||||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||||
@@ -102,10 +109,6 @@ pub fn kmain() -> ! {
|
|||||||
.read(0, 0, 0)
|
.read(0, 0, 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
unsafe {
|
|
||||||
*(0xDEADBEEF as *mut u32) = 0xBAADF00D;
|
|
||||||
};
|
|
||||||
|
|
||||||
// let file = vfs_open("/example.txt").unwrap();
|
// let file = vfs_open("/example.txt").unwrap();
|
||||||
|
|
||||||
// as a sign that we didnt panic
|
// 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);
|
.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_export]
|
||||||
macro_rules! println {
|
macro_rules! println {
|
||||||
() => ($crate::print!("\n"));
|
() => ($crate::print!("\n"));
|
||||||
@@ -176,26 +199,31 @@ macro_rules! print {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[repr(u8)]
|
||||||
macro_rules! log_info {
|
enum LogLevel {
|
||||||
($($arg:tt)*) => ($crate::println!("\x1B[97m[ \x1B[90m? \x1B[97m]\x1B[0m {}", &alloc::format!($($arg)*)));
|
Trace = 0,
|
||||||
|
Debug,
|
||||||
|
Info,
|
||||||
|
Warn,
|
||||||
|
Error,
|
||||||
|
Fatal,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! log_serial {
|
macro_rules! log {
|
||||||
($($arg:tt)*) => (
|
($level:expr, $($arg:tt)*) => {{
|
||||||
$crate::drivers::serial::write_string(&alloc::format!($($arg)*).replace('\n', "\n\r"))
|
if ($level as u8) >= $crate::LOG_LEVEL {
|
||||||
);
|
let color_code = match $level {
|
||||||
}
|
$crate::LogLevel::Trace => "\x1B[90m",
|
||||||
|
$crate::LogLevel::Debug => "\x1B[94m",
|
||||||
#[macro_export]
|
$crate::LogLevel::Info => "\x1B[92m",
|
||||||
macro_rules! log_error {
|
$crate::LogLevel::Warn => "\x1B[93m",
|
||||||
($($arg:tt)*) => ($crate::println!("\x1B[97m[ \x1B[91m! \x1B[97m]\x1B[0m {}", &alloc::format!($($arg)*)));
|
$crate::LogLevel::Error => "\x1B[91m",
|
||||||
}
|
$crate::LogLevel::Fatal => "\x1B[95m",
|
||||||
|
};
|
||||||
#[macro_export]
|
$crate::println!("\x1B[97m[ {}* \x1B[97m]\x1B[0;m {}", color_code, &alloc::format!($($arg)*))
|
||||||
macro_rules! log_ok {
|
}
|
||||||
($($arg:tt)*) => ($crate::println!("\x1B[97m[ \x1B[92m* \x1B[97m]\x1B[0;m {}", &alloc::format!($($arg)*)));
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -229,7 +257,7 @@ fn parse_kernel_cmdline() {
|
|||||||
|
|
||||||
let kernel_arguments = cmdline.unwrap().split_whitespace().collect::<Vec<&str>>();
|
let kernel_arguments = cmdline.unwrap().split_whitespace().collect::<Vec<&str>>();
|
||||||
|
|
||||||
crate::println!("{kernel_arguments:?}");
|
// crate::log!(LogLevel::Trace, "{kernel_arguments:?}");
|
||||||
|
|
||||||
for item in kernel_arguments {
|
for item in kernel_arguments {
|
||||||
let parts: Vec<&str> = item.split('=').collect();
|
let parts: Vec<&str> = item.split('=').collect();
|
||||||
|
|||||||
@@ -55,56 +55,75 @@ pub fn init_allocator() {
|
|||||||
|
|
||||||
drop(allocator_lock);
|
drop(allocator_lock);
|
||||||
|
|
||||||
crate::println!(
|
|
||||||
"{} of memory available",
|
|
||||||
PHYSICAL_MEMORY_MANAGER.total_memory().label_bytes()
|
|
||||||
);
|
|
||||||
|
|
||||||
// log_memory_map();
|
// log_memory_map();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Label {
|
pub enum ByteLabelKind {
|
||||||
BYTE(usize),
|
BYTE,
|
||||||
KIB(usize),
|
KIB,
|
||||||
MIB(usize),
|
MIB,
|
||||||
GIB(usize),
|
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 {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
match self {
|
let size = self.count;
|
||||||
Label::BYTE(count) => {
|
|
||||||
write!(f, "{count} Byte(s)")
|
match self.byte_label {
|
||||||
|
ByteLabelKind::BYTE => {
|
||||||
|
write!(f, "{size} Byte")?;
|
||||||
}
|
}
|
||||||
Label::KIB(count) => {
|
ByteLabelKind::KIB => {
|
||||||
write!(f, "{count} KiB(s)")
|
write!(f, "{size} KiB")?;
|
||||||
}
|
}
|
||||||
Label::MIB(count) => {
|
ByteLabelKind::MIB => {
|
||||||
write!(f, "{count} MiB(s)")
|
write!(f, "{size} MiB")?;
|
||||||
}
|
}
|
||||||
Label::GIB(count) => {
|
ByteLabelKind::GIB => {
|
||||||
write!(f, "{count} GiB(s)")
|
write!(f, "{size} GiB")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if size != 1 {
|
||||||
|
write!(f, "s")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub trait LabelBytes {
|
pub trait LabelBytes {
|
||||||
fn label_bytes(&self) -> Label;
|
fn label_bytes(&self) -> ByteLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LabelBytes for usize {
|
impl LabelBytes for usize {
|
||||||
fn label_bytes(&self) -> Label {
|
fn label_bytes(&self) -> ByteLabel {
|
||||||
let bytes = *self;
|
let bytes = *self;
|
||||||
|
|
||||||
|
let mut byte_label = ByteLabel {
|
||||||
|
byte_label: ByteLabelKind::BYTE,
|
||||||
|
count: bytes,
|
||||||
|
};
|
||||||
|
|
||||||
if bytes >> 30 > 0 {
|
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 {
|
} 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 {
|
} else if bytes >> 10 > 0 {
|
||||||
return Label::KIB(bytes >> 10);
|
byte_label.byte_label = ByteLabelKind::KIB;
|
||||||
} else {
|
byte_label.count = bytes >> 10;
|
||||||
return Label::BYTE(bytes);
|
// return Label::KIB(bytes >> 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return byte_label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user