Newer
Older
#![deny(
clippy::complexity,
clippy::correctness,
clippy::nursery,
clippy::pedantic,
clippy::perf,
clippy::restriction,
clippy::blanket_clippy_restriction_lints,
clippy::else_if_without_else,
clippy::exhaustive_enums,
clippy::exhaustive_structs,
clippy::match_same_arms,
clippy::match_wildcard_for_single_variants,
clippy::missing_trait_methods,
clippy::mod_module_files,
clippy::panic_in_result_fn,
clippy::pattern_type_mismatch,
clippy::separated_literal_suffix,
clippy::shadow_reuse,
clippy::shadow_unrelated,
clippy::unreachable,
clippy::unwrap_in_result,
clippy::wildcard_in_or_patterns,
const_item_mutation
)]
#![cfg_attr(
test,
allow(
clippy::assertions_on_result_states,
clippy::enum_glob_use,
clippy::indexing_slicing,
clippy::non_ascii_literal,
clippy::too_many_lines,
clippy::unwrap_used,
#![no_std]
#![no_main]
#![feature(abi_x86_interrupt)]
#![feature(alloc_error_handler)]
#![feature(const_mut_refs)]
#![feature(const_trait_impl)]
#![feature(custom_test_frameworks)]
#![feature(no_coverage)]
#![feature(strict_provenance)]
#![reexport_test_harness_main = "test_main"]
#![test_runner(test::runner)]
extern crate alloc;
mod encoding;
mod kernel;
mod macros;
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;
use log::{logger, set_logger, set_max_level, LevelFilter};
#[cfg(test)]
use test::exit;
use user::tty::print_key;
#[cfg(not(test))]
/// 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]
fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
set_logger(&SYS_LOGGER).expect("Could not initialize the logger");
set_max_level(LevelFilter::Trace);
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) -> ! {
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#[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);