gila/src/kernel/main.rs
August 63edda1d28
Some checks failed
Continuous Integration / Check (push) Failing after 1m56s
Continuous Integration / Clippy (push) Failing after 50s
Fix badly loaded TSS descriptor
2026-10-08 18:33:18 +00:00

119 lines
3.6 KiB
Rust

// Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: MIT
#![no_std]
#![no_main]
#![feature(abi_x86_interrupt)]
mod arch;
mod boot;
mod constants;
mod interrupt;
#[macro_use]
mod log;
mod memory;
mod panic;
mod process;
mod util;
use arch::x86_64::serial::SerialPort;
use boot::{BASE_REVISION, params};
use constants::*;
use log::*;
use memory::alloc::{boxed::Box, format, vec};
use params::*;
use lazy_static::lazy_static;
use spin::mutex::Mutex;
use x86_64::VirtAddr;
use crate::{arch::x86_64::gdt::SELECTORS, boot::modules::MODULE_RESPONSE};
lazy_static! {
pub static ref SERIAL_3F8: Mutex<SerialPort> = Mutex::new(
arch::x86_64::serial::SerialPort::try_from_port(0x3f8).expect("Could not create port")
);
}
#[unsafe(no_mangle)]
unsafe extern "C" fn main() -> ! {
// CRITICAL AREA
// Nothing non-essential should be done until we can initialize logging
// Otherwise it will fail silently
// Assert supported bootloader version
assert!(BASE_REVISION.is_supported());
// Set up logging level from params
// Nothing we can do here if this fails since no log subscribers are initialized yet
if let Some(level) = PARAMS.get("-loglevel")
&& let Ok(parsed_level) = LogLevel::try_from(level.as_str())
{
LOGGER.lock().level = parsed_level;
}
// Add subscribers to logger
if let Some(device) = PARAMS.get("-logdev") {
let log_device_list: vec::Vec<&str> = device.split(',').collect();
if log_device_list.contains(&"display") {
// Append display console to log subs
}
if log_device_list.contains(&"serial") {
// TODO: Set up device discovery
let serial_logger = |msg: &str| SERIAL_3F8.lock().log_writeln(msg);
LOGGER.lock().add_device(Box::new(serial_logger));
}
log_trace!("Configured kernel logging devices");
let log_level = LOGGER.lock().level;
log_info!("Log level: {:?}", log_level);
}
// END OF CRITICAL AREA
// Fallible code can be placed below this comment
let _ = arch::startup::init();
// Initialize all statics so the bootloader memory can be reclaimed
memory::init_statics();
log_info!(
"Boot cmdline: {} {}",
EXECUTABLE_FILE_RESPONSE.executable_file().path(),
EXECUTABLE_FILE_RESPONSE.executable_file().cmdline()
);
// Branding
for line in ASCII_LOGO {
let mut locked = SERIAL_3F8.lock();
locked.log_write("\t\t");
locked.log_writeln(line);
}
SERIAL_3F8
.lock()
.log_writeln("\tWelcome to the Gila microkernel!\n");
log_info!("Booting gila version {}", kernel_version_string());
log_info!("Trans rights!");
boot::modules::log_modules();
memory::log_memory();
memory::log_address();
log_info!(
"TSS descriptor: 0x{:08x} {:08x}",
SELECTORS.gdt.entries()[SELECTORS.sel_tss.index() as usize + 1].raw(),
SELECTORS.gdt.entries()[SELECTORS.sel_tss.index() as usize].raw()
);
if let Some(modules_list) = *MODULE_RESPONSE
&& modules_list.modules()[0].path().ends_with("/userboot.bin")
{
let ub = modules_list.modules()[0];
log_info!("Found userboot: {} {}", ub.path(), ub.cmdline());
// TODO: remap userboot as user pages
let start_addr = VirtAddr::from_ptr(ub.data() as *const [u8]);
log_trace!("Userboot start address: 0x{:x}", start_addr);
arch::startup::jump_to_usermode(VirtAddr::new(0xffffffff80000000), start_addr)
} else {
panic!("Userboot not found, cannot boot!");
}
}