commit - 69cdec6c61e7866110f917f1f5bf4d3381b029a5
commit + 6cf82f681b402f01a9898e748f2533858f618040
blob - fb74be1776407495f4175388b8c3302e8a839e4e
blob + 39e47494c84db6c996a81fadd00f0fe65efc3e7a
--- src/main.rs
+++ src/main.rs
#![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();