Commit Diff


commit - 69cdec6c61e7866110f917f1f5bf4d3381b029a5
commit + 6cf82f681b402f01a9898e748f2533858f618040
blob - fb74be1776407495f4175388b8c3302e8a839e4e
blob + 39e47494c84db6c996a81fadd00f0fe65efc3e7a
--- src/main.rs
+++ src/main.rs
@@ -18,89 +18,114 @@
 #![no_std]
 #![no_main]
 
-use core::arch::asm;
+extern crate alloc;
 
-use limine::{BaseRevision, RequestsStartMarker, RequestsEndMarker};
+mod gdt;
+mod idt;
+mod ipc;
+mod paging;
+mod pic;
+mod pit;
+mod pmm;
+mod port;
+mod sched;
+mod serial;
+mod syscall;
+mod task;
+mod vga;
 
+#[path = "alloc.rs"]
+mod kernel_alloc;
+
+use limine::request::{HhdmRequest, MemmapRequest};
+use limine::{
+    BaseRevision, RequestsEndMarker, RequestsStartMarker,
+};
+
 #[used]
 #[unsafe(link_section = ".requests_start")]
-pub static REQUEST_START: RequestsStartMarker = RequestsStartMarker::new();
+pub static REQUEST_START: RequestsStartMarker =
+    RequestsStartMarker::new();
 
 #[used]
 #[unsafe(link_section = ".requests")]
 pub static BASE_REVISION: BaseRevision = BaseRevision::new();
 
+#[used]
+#[unsafe(link_section = ".requests")]
+pub static HHDM_REQUEST: HhdmRequest = HhdmRequest::new();
+
+#[used]
+#[unsafe(link_section = ".requests")]
+pub static MEMMAP_REQUEST: MemmapRequest =
+    MemmapRequest::new();
+
+static mut SYSCALL_STACK: [u8; 16384] = [0; 16384];
+
 #[unsafe(no_mangle)]
 pub unsafe extern "C" fn kmain() -> ! {
-    serial_init();
-    serial_print("OMK: Olivia MicroKernel\n");
-    serial_print("ALIVE\n");
+    serial::init();
+    serial::print("OMK: Olivia MicroKernel\n");
 
-    vga_write("ALIVE", 0x0F);
+    gdt::init();
+    idt::init();
+    pic::init();
+    pit::init(100);
 
-    loop {}
+    let hhdm_offset = HHDM_REQUEST
+        .response()
+        .map(|r| r.offset)
+        .unwrap_or(0);
+    paging::init(hhdm_offset);
+
+    if let Some(resp) = MEMMAP_REQUEST.response() {
+        pmm::init(resp.entries());
+    }
+
+    kernel_alloc::init_heap(hhdm_offset, &mut || {
+        pmm::alloc_page()
+    });
+
+    let kern_stack_top = unsafe {
+        let ptr = (&raw const SYSCALL_STACK) as *const u8;
+        ptr.add(size_of_val(&*(&raw const SYSCALL_STACK)))
+            as u64
+    };
+    syscall::init(kern_stack_top);
+    gdt::set_kernel_stack(kern_stack_top);
+
+    sched::init();
+
+    serial::print("kernel ready\n");
+
+    // Enable interrupts
+    unsafe {
+        core::arch::asm!("sti");
+    }
+
+    // The kernel's job is done: hardware initialized,
+    // syscall interface ready, scheduler running.
+    // In a complete OS, the init process (loaded from
+    // initrd) would be launched here as a Ring 3 task.
+    // For now, idle until interrupted.
+    loop {
+        unsafe {
+            core::arch::asm!("hlt");
+        }
+    }
 }
 
 #[panic_handler]
 fn panic(_info: &core::panic::PanicInfo) -> ! {
-    loop {}
-}
-
-const COM1: u16 = 0x3F8;
-
-unsafe fn outb(port: u16, val: u8) {
-    unsafe {
-        asm!("out dx, al", in("dx") port, in("al") val);
-    }
-}
-
-unsafe fn inb(port: u16) -> u8 {
-    let val: u8;
-    unsafe {
-        asm!("in al, dx", out("al") val, in("dx") port);
-    }
-    val
-}
-
-fn serial_init() {
-    unsafe {
-        outb(COM1 + 1, 0x00);
-        outb(COM1 + 3, 0x80);
-        outb(COM1 + 0, 0x03);
-        outb(COM1 + 1, 0x00);
-        outb(COM1 + 3, 0x03);
-        outb(COM1 + 2, 0xC7);
-        outb(COM1 + 4, 0x0B);
-    }
-}
-
-fn serial_putc(c: u8) {
-    while unsafe { inb(COM1 + 5) } & 0x20 == 0 {}
-    unsafe {
-        outb(COM1, c);
-    }
-}
-
-fn serial_print(s: &str) {
-    for b in s.bytes() {
-        if b == b'\n' {
-            serial_putc(b'\r');
-        }
-        serial_putc(b);
-    }
-}
-
-fn vga_write(s: &str, color: u8) {
-    let vga = 0xb8000 as *mut u16;
-    for (i, b) in s.bytes().enumerate() {
+    serial::print("PANIC\n");
+    loop {
         unsafe {
-            vga.add(i).write_volatile(
-                (color as u16) << 8 | b as u16
-            );
+            core::arch::asm!("cli", "hlt");
         }
     }
 }
 
 #[used]
 #[unsafe(link_section = ".requests_end")]
-pub static REQUEST_END: RequestsEndMarker = RequestsEndMarker::new();
+pub static REQUEST_END: RequestsEndMarker =
+    RequestsEndMarker::new();