Skip to content
Snippets Groups Projects
main.rs 3.6 KiB
Newer Older
//! `SkavOS`
pigeonmoelleux's avatar
pigeonmoelleux committed

#![deny(
    clippy::complexity,
    clippy::correctness,
    clippy::nursery,
    clippy::pedantic,
    clippy::perf,
    clippy::restriction,
    clippy::style
pigeonmoelleux's avatar
pigeonmoelleux committed
)]
#![allow(
    clippy::arithmetic_side_effects,
    clippy::as_conversions,
pigeonmoelleux's avatar
pigeonmoelleux committed
    clippy::blanket_clippy_restriction_lints,
    clippy::else_if_without_else,
    clippy::exhaustive_enums,
    clippy::exhaustive_structs,
    clippy::expect_used,
pigeonmoelleux's avatar
pigeonmoelleux committed
    clippy::implicit_return,
    clippy::integer_arithmetic,
    clippy::integer_division,
pigeonmoelleux's avatar
pigeonmoelleux committed
    clippy::match_same_arms,
    clippy::match_wildcard_for_single_variants,
    clippy::missing_trait_methods,
    clippy::mod_module_files,
    clippy::panic,
pigeonmoelleux's avatar
pigeonmoelleux committed
    clippy::panic_in_result_fn,
    clippy::pattern_type_mismatch,
    clippy::question_mark_used,
pigeonmoelleux's avatar
pigeonmoelleux committed
    clippy::separated_literal_suffix,
    clippy::shadow_reuse,
    clippy::shadow_unrelated,
    clippy::unreachable,
    clippy::unwrap_in_result,
    clippy::wildcard_in_or_patterns,
    const_item_mutation
pigeonmoelleux's avatar
pigeonmoelleux committed
)]
#![cfg_attr(
    test,
    allow(
        clippy::assertions_on_result_states,
        clippy::collection_is_never_read,
pigeonmoelleux's avatar
pigeonmoelleux committed
        clippy::enum_glob_use,
        clippy::indexing_slicing,
        clippy::non_ascii_literal,
        clippy::too_many_lines,
        clippy::unwrap_used,
        clippy::wildcard_imports
pigeonmoelleux's avatar
pigeonmoelleux committed
    )
)]
#![no_std]
#![no_main]
#![feature(abi_x86_interrupt)]
#![feature(alloc_error_handler)]
#![feature(const_extern_fn)]
#![feature(const_mut_refs)]
#![feature(const_trait_impl)]
#![feature(custom_test_frameworks)]
pigeonmoelleux's avatar
pigeonmoelleux committed
#![feature(error_in_core)]
#![feature(no_coverage)]
#![feature(strict_provenance)]
#![reexport_test_harness_main = "test_main"]
#![test_runner(test::runner)]
pigeonmoelleux's avatar
pigeonmoelleux committed

extern crate alloc;

mod encoding;
mod kernel;
mod macros;
mod mutex;
pigeonmoelleux's avatar
pigeonmoelleux committed
mod syslog;
mod user;

#[cfg(test)]
mod test;

use core::alloc::Layout;

use bootloader_api::config::{Mapping, Mappings};
use bootloader_api::{entry_point, BootInfo, BootloaderConfig};
use kernel::task::executor::Executor;
use kernel::task::Task;
pigeonmoelleux's avatar
pigeonmoelleux committed
use log::{logger, set_logger, set_max_level, LevelFilter};
#[cfg(test)]
use test::exit;
use user::tty::print_key;
#[cfg(not(test))]
use x86_64::instructions;

pigeonmoelleux's avatar
pigeonmoelleux committed
use self::syslog::SYS_LOGGER;

/// Configuration of the bootloader
///
/// The only change from the default configuration is the dynamic mapping to the physical memory
const BOOTLOADER_CONFIG: BootloaderConfig = {
    let mut config = BootloaderConfig::new_default();
    config.mappings = Mappings::new_default();
    config.mappings.page_table_recursive = Some(Mapping::Dynamic);
    config
};

/// Main function of the kernel
#[no_coverage]
#[allow(unreachable_code)]
fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
pigeonmoelleux's avatar
pigeonmoelleux committed
    set_logger(&SYS_LOGGER).expect("Could not initialize the logger");
    set_max_level(LevelFilter::Trace);

    kernel::init(boot_info);

    #[cfg(test)]
    {
        test_main();
        exit();
    };
    let mut executor = Executor::new();
    executor.spawn(Task::new(print_key()));
    executor.run();
}

/// Panic prints on screen the reason
#[panic_handler]
#[no_coverage]
fn panic(info: &core::panic::PanicInfo) -> ! {
pigeonmoelleux's avatar
pigeonmoelleux committed
    logger().flush();

    #[cfg(not(test))]
    {
        println!("kernel panic: {:#?}", info);

        loop {
            instructions::hlt();
        }
    }

    #[cfg(test)]
    {
        use qemu_exit::QEMUExit;

        println!("[failed]\n");
        println!("Error: {}\n", info);

        qemu_exit::X86::new(0xf4, 13).exit_failure();
    }
}

/// Allocation failure handler
#[alloc_error_handler]
#[no_coverage]
fn alloc_error_handler(layout: Layout) -> ! {
    panic!("allocation error: {:?}", layout);
}

entry_point!(kernel_main, config = &BOOTLOADER_CONFIG);