1#![no_std]
7#![no_main]
8#![feature(abi_x86_interrupt)]
9#![allow(special_module_name)]
10
11extern crate alloc;
12
13mod arch;
14mod cpu;
15mod drivers;
16mod ipc;
17mod kprint;
18mod lib;
19mod mm;
20mod net;
21mod sched;
22mod state;
23mod syscall;
24mod vfs;
25
26mod config;
27
28use crate::lib::addr::VirtAddr;
29use crate::lib::panic::kernel_panic;
30use crate::lib::panic_codes::PanicCode;
31use crate::lib::types::boot_info::{BootInfo, FramebufferInfo};
32use crate::sched::spawn::{SpawnError, spawn_from_elf};
33use crate::state::kstate::KSTATE;
34use crate::state::simple_state::SIMPLE_STATE;
35
36#[repr(align(8))]
38struct AlignedBytes<const N: usize> {
39 bytes: [u8; N],
40}
41const USER_BINARY_LEN: usize = include_bytes!("../resources/user-binary").len();
42static USER_BINARY_ALIGNED: AlignedBytes<USER_BINARY_LEN> = AlignedBytes {
43 bytes: *include_bytes!("../resources/user-binary"),
44};
45pub static USER_BINARY: &[u8] = &USER_BINARY_ALIGNED.bytes;
46
47
48pub(crate) fn kernel_main(boot_info: BootInfo) -> ! {
50 KSTATE.mm.set_hhdm_offset(boot_info.hhdm_offset);
52 KSTATE.kprint.config().set_max_log_level(boot_info.cmdline.log_level);
53 KSTATE.kprint.config().set_log_targets(boot_info.cmdline.log_targets);
54 SIMPLE_STATE.set_panic_action(boot_info.cmdline.panic_action);
55
56 basic_fb_init(&boot_info.framebuffer);
57
58 kinfo!("Hello, Ferrite!");
59 kdebug!("Debug kprint is active!");
60
61 unsafe { arch::init(&boot_info) };
67 cpu::instructions::enable_interrupts();
68
69
70 let pid = match unsafe { spawn_from_elf(USER_BINARY, 0) } {
72 Ok(p) => p,
73 Err(e) => {
74 kernel_panic(
75 match e {
76 SpawnError::OutOfMemory => PanicCode::OutOfMemory,
77 SpawnError::InvalidBinary => PanicCode::NoWorkingInit,
78 SpawnError::MappingCollision => PanicCode::MemoryMappingCollision
79 },
80 "Could not spawn the USER_BINARY process"
81 )
82 }
83 };
84 KSTATE.sched.set_active_pid(pid);
85
86 unsafe {
87 let (page_ptr, kernel_stack, rip, rsp) = KSTATE.sched.with_process(pid, |p| {
88 p.status = sched::process::ProcessStatus::Running;
89 (p.addr_space.page_ptr(), p.kernel_stack_top, p.regs.rip, p.regs.rsp)
90 }).unwrap_or_else(
91 || kernel_panic(
92 PanicCode::ProcessNotFound,
93 "Could not fetch process info from process map"
94 )
95 );
96
97 KSTATE.cpu.bsp_cpu_state().set_kernel_stack_top(kernel_stack);
98
99 cpu::userspace::initial_userspace_jump(
100 page_ptr.as_u64() - KSTATE.mm.hhdm_offset(),
101 rip,
102 VirtAddr::new(rsp)
103 );
104 }
105
106 #[allow(unreachable_code)]
107 {
108 kemerg!("Init process died or was killed, panic'ing");
109 kernel_panic(
110 PanicCode::InitProcessDied,
111 "The init process (PID 1) has died, aborting!"
112 );
113 }
114}
115
116fn basic_fb_init(fb: &FramebufferInfo) {
118 use crate::drivers::gpu::basic_fb::font::Psf2Font;
119 use crate::drivers::gpu::basic_fb::framebuffer::BasicFramebuffer;
120
121 unsafe {
123 SIMPLE_STATE.init_basic_fb(BasicFramebuffer::new(fb));
124 SIMPLE_STATE.init_basic_fb_psf2_font(Psf2Font::init());
125 }
126}