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(int_roundings)]
#![feature(no_coverage)]
#![feature(strict_provenance)]
#![feature(vec_into_raw_parts)]
#![reexport_test_harness_main = "test_main"]
#![test_runner(test::runner)]
use alloc::sync::Arc;
use alloc::vec::Vec;
use core::alloc::Layout;
use bootloader_api::config::{Mapping, Mappings};
use bootloader_api::{entry_point, BootInfo, BootloaderConfig};
use kernel::device::storage::Device;
use kernel::device::{STORAGE_CONTROLLERS, UEFI_UUID};
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))]
use x86_64::structures::paging::PageTableFlags;
use crate::kernel::interrupt::cmos::CMOS;
use crate::kernel::interrupt::pit::sleep;
use crate::kernel::memory::vmm::VIRTUAL_MEMORY_MANAGER;
/// 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 storage_devices = STORAGE_CONTROLLERS
.get()
.expect("Storage controllers have not been initialized yet")
.iter()
.flat_map(|controller| controller.lock().devices())
.collect::<Vec<Arc<Mutex<dyn Device + Send>>>>()
.into_iter()
.filter(|device| device.lock().uuid() != UEFI_UUID)
.collect::<Vec<Arc<Mutex<dyn Device + Send>>>>();
if let Some(device) = storage_devices.first() {
println!("Hello world!");
let rtc = CMOS.rtc();
println!("It is currently : {:0>2}:{:0>2}:{:0>2} (UTC+0)", rtc.hour, rtc.minute, rtc.second);
// let page = VIRTUAL_MEMORY_MANAGER
// .lock()
// .as_mut()
// .unwrap()
// .new_page(PageTableFlags::PRESENT | PageTableFlags::WRITABLE);
// println!("{:?}", page);
// loop {
// sleep(1000);
// let rtc = CMOS.rtc();
// println!("It is currently : {:0>2}:{:0>2}:{:0>2} (UTC+0)", rtc.hour, rtc.minute, rtc.second);
// }
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) -> ! {
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#[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);