1#![no_std]
7#![no_main]
8#![feature(abi_x86_interrupt)]
9
10extern crate alloc;
11
12mod types;
13mod panic;
14mod arch;
15mod logging;
16mod screen;
17mod mem;
18mod state;
19mod config;
20
21use spin::Once;
22use limine::request::{FramebufferRequest, HhdmRequest, MemmapRequest};
23use crate::arch::instructions;
24use crate::panic::kernel_panic;
25use crate::types::panic_codes::PanicCode;
26
27struct SimpleKernelState {
32 serial: Once<logging::serial::Serial>,
33 basic_fb: Once<screen::basic::framebuffer::BasicFramebuffer>,
34 basic_fb_psf2_font: Once<screen::basic::font::Psf2Font>,
35 pmm: Once<mem::pmm::Pmm>,
36 vmm: Once<mem::vmm::Vmm>,
37}
38
39static LIMINE_FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new();
41
42static LIMINE_MEMMAP_REQUEST: MemmapRequest = MemmapRequest::new();
44
45static LIMINE_HHDM_REQUEST: HhdmRequest = HhdmRequest::new();
47
48pub(crate) static SIMPLE_STATE: SimpleKernelState = SimpleKernelState {
50 serial: Once::new(),
51 basic_fb: Once::new(),
52 basic_fb_psf2_font: Once::new(),
53 pmm: Once::new(),
54 vmm: Once::new(),
55};
56
57#[no_mangle]
59extern "C" fn kmain() -> ! {
60 {
61 use logging::serial::Serial;
62 use logging::_serial::{SerialPort, _Serial};
63
64 SIMPLE_STATE.serial.call_once(|| -> Serial {
65 Serial::new(SerialPort::Serial1)
66 });
67 let res = SIMPLE_STATE.serial.get().unwrap().init();
68 if !res.is_ok() {
69 kernel_panic(
70 PanicCode::InitFailure,
71 "Failed to initialize serial for kernel logging"
72 );
73 }
74 }
75
76 {
77 use crate::screen::basic::framebuffer::BasicFramebuffer;
78 use crate::screen::basic::font::Psf2Font;
79
80 if let Some(fb_response) = LIMINE_FRAMEBUFFER_REQUEST.response() {
81 if let Some(fb) = fb_response.framebuffers().first() {
82 SIMPLE_STATE.basic_fb.call_once(|| -> BasicFramebuffer {
83 BasicFramebuffer::new(fb)
84 });
85 SIMPLE_STATE.basic_fb_psf2_font.call_once(|| -> Psf2Font {
86 Psf2Font::init()
87 });
88 }
89 }
90 }
91
92 kinfo!("Hello, FerriteOS!");
93 kdebug!("Debug logging is active!");
94
95 arch::init();
97
98 {
99 if let Some(memmap_response) = LIMINE_MEMMAP_REQUEST.response() {
101 if let Some(hhdm_response) = LIMINE_HHDM_REQUEST.response() {
102 SIMPLE_STATE.pmm.call_once(|| mem::pmm::Pmm::init(memmap_response.entries(), hhdm_response.offset) );
103 SIMPLE_STATE.vmm.call_once(|| mem::vmm::Vmm::init(SIMPLE_STATE.pmm.get().unwrap(), hhdm_response.offset));
104 }
105 }
106 }
107
108 mem::heap::init(SIMPLE_STATE.pmm.get().unwrap(), SIMPLE_STATE.vmm.get().unwrap());
110
111 instructions::enable_interrupts();
112
113
114 kinfo!("Kernel ran successfully!");
115
116 loop {
118 unsafe {
119 core::arch::asm!("hlt", options(nostack, nomem))
120 }
121 }
122}