modularity
This commit is contained in:
parent
c9f1f6466d
commit
108ddb7cf9
@ -15,6 +15,7 @@ compile_error!(
|
|||||||
pub mod x86_64;
|
pub mod x86_64;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub use x86_64::asm;
|
pub use x86_64::asm;
|
||||||
|
pub use x86_64::startup;
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub mod aarch64;
|
pub mod aarch64;
|
||||||
|
|||||||
@ -8,3 +8,4 @@ pub mod gdt;
|
|||||||
pub mod intel_virt;
|
pub mod intel_virt;
|
||||||
pub mod interrupts;
|
pub mod interrupts;
|
||||||
pub mod serial;
|
pub mod serial;
|
||||||
|
pub mod startup;
|
||||||
|
|||||||
42
src/kernel/arch/x86_64/startup.rs
Normal file
42
src/kernel/arch/x86_64/startup.rs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
use x86_64::{VirtAddr, registers::rflags::RFlags, structures::idt::InterruptStackFrameValue};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
arch::{
|
||||||
|
asm::ltr,
|
||||||
|
x86_64::{gdt::SELECTORS, interrupts::IDT},
|
||||||
|
},
|
||||||
|
log::{LOGGER, LogLevel},
|
||||||
|
log_info,
|
||||||
|
memory::alloc::format,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn init() -> Result<(), ()> {
|
||||||
|
// Ensure GDT exists
|
||||||
|
SELECTORS.gdt.load();
|
||||||
|
log_info!("GDT loaded!");
|
||||||
|
// Load IDT
|
||||||
|
IDT.load();
|
||||||
|
log_info!("IDT loaded!");
|
||||||
|
x86_64::registers::model_specific::Star::write(
|
||||||
|
SELECTORS.sel_user_code,
|
||||||
|
SELECTORS.sel_user_stack,
|
||||||
|
SELECTORS.sel_kernel_code,
|
||||||
|
SELECTORS.sel_kernel_stack,
|
||||||
|
)
|
||||||
|
.expect("Segment order in GDT is bad");
|
||||||
|
ltr(SELECTORS.sel_tss.index());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn jump_to_usermode(sp: VirtAddr, ip: VirtAddr) -> ! {
|
||||||
|
unsafe {
|
||||||
|
InterruptStackFrameValue::new(
|
||||||
|
ip,
|
||||||
|
SELECTORS.sel_user_code,
|
||||||
|
RFlags::INTERRUPT_FLAG,
|
||||||
|
sp,
|
||||||
|
SELECTORS.sel_user_stack,
|
||||||
|
)
|
||||||
|
.iretq();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -18,7 +18,6 @@ mod util;
|
|||||||
|
|
||||||
use core::ptr::addr_of;
|
use core::ptr::addr_of;
|
||||||
|
|
||||||
use arch::x86_64::interrupts::IDT;
|
|
||||||
use arch::x86_64::serial::SerialPort;
|
use arch::x86_64::serial::SerialPort;
|
||||||
use boot::{BASE_REVISION, params, *};
|
use boot::{BASE_REVISION, params, *};
|
||||||
use constants::*;
|
use constants::*;
|
||||||
@ -31,16 +30,10 @@ use limine::firmware::{
|
|||||||
FIRMWARE_TYPE_EFI32, FIRMWARE_TYPE_EFI64, FIRMWARE_TYPE_SBI, FIRMWARE_TYPE_X86BIOS,
|
FIRMWARE_TYPE_EFI32, FIRMWARE_TYPE_EFI64, FIRMWARE_TYPE_SBI, FIRMWARE_TYPE_X86BIOS,
|
||||||
};
|
};
|
||||||
use spin::mutex::Mutex;
|
use spin::mutex::Mutex;
|
||||||
use x86_64::{VirtAddr, registers::rflags::RFlags, structures::idt::InterruptStackFrameValue};
|
use x86_64::VirtAddr;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{
|
arch::x86_64::cpuid::{CPUID, virt_supported},
|
||||||
asm::ltr,
|
|
||||||
x86_64::{
|
|
||||||
cpuid::{CPUID, virt_supported},
|
|
||||||
gdt::SELECTORS,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
boot::modules::MODULE_RESPONSE,
|
boot::modules::MODULE_RESPONSE,
|
||||||
memory::paging::active_root_table,
|
memory::paging::active_root_table,
|
||||||
};
|
};
|
||||||
@ -79,31 +72,22 @@ unsafe extern "C" fn main() -> ! {
|
|||||||
LOGGER.lock().add_device(Box::new(serial_logger));
|
LOGGER.lock().add_device(Box::new(serial_logger));
|
||||||
}
|
}
|
||||||
log_trace!("Configured kernel logging devices");
|
log_trace!("Configured kernel logging devices");
|
||||||
|
let log_level = LOGGER.lock().level;
|
||||||
|
log_info!("Log level: {:?}", log_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
// END OF CRITICAL AREA
|
// END OF CRITICAL AREA
|
||||||
// Fallible code can be placed below this comment
|
// Fallible code can be placed below this comment
|
||||||
|
|
||||||
|
let _ = arch::startup::init();
|
||||||
// Initialize all statics so the bootloader memory can be reclaimed
|
// Initialize all statics so the bootloader memory can be reclaimed
|
||||||
memory::init_statics();
|
memory::init_statics();
|
||||||
|
|
||||||
// Ensure IDT exists
|
|
||||||
SELECTORS.gdt.load();
|
|
||||||
log_info!("GDT loaded!");
|
|
||||||
IDT.load();
|
|
||||||
log_info!("IDT loaded!");
|
|
||||||
|
|
||||||
log_info!(
|
log_info!(
|
||||||
"Kernel cmdline: {}",
|
"Boot cmdline: {} {}",
|
||||||
|
EXECUTABLE_FILE_RESPONSE.executable_file().path(),
|
||||||
EXECUTABLE_FILE_RESPONSE.executable_file().cmdline()
|
EXECUTABLE_FILE_RESPONSE.executable_file().cmdline()
|
||||||
);
|
);
|
||||||
log_info!(
|
|
||||||
"Kernel file path: {}",
|
|
||||||
EXECUTABLE_FILE_RESPONSE.executable_file().path()
|
|
||||||
);
|
|
||||||
|
|
||||||
let log_level = log::LOGGER.lock().level;
|
|
||||||
log_info!("Log level: {:?}", log_level);
|
|
||||||
|
|
||||||
// Branding
|
// Branding
|
||||||
for line in ASCII_LOGO {
|
for line in ASCII_LOGO {
|
||||||
@ -181,19 +165,12 @@ unsafe extern "C" fn main() -> ! {
|
|||||||
}
|
}
|
||||||
log_info!("Virtualization provider: {:?}", virt_supported());
|
log_info!("Virtualization provider: {:?}", virt_supported());
|
||||||
|
|
||||||
{
|
let root_ptable_info = unsafe { active_root_table() };
|
||||||
let root_ptable_info = unsafe { active_root_table() };
|
log_info!(
|
||||||
log_info!(
|
"Root page table is Level {} at 0x{:x}",
|
||||||
"Root page table is Level {} at 0x{:x}",
|
root_ptable_info.1,
|
||||||
root_ptable_info.1,
|
addr_of!(*root_ptable_info.0) as usize
|
||||||
addr_of!(*root_ptable_info.0) as usize
|
);
|
||||||
);
|
|
||||||
// This is an expensive function. Only run it if we're actually logging the results.
|
|
||||||
//let loglevel = LOGGER.lock().level;
|
|
||||||
//if loglevel <= LogLevel::Trace {
|
|
||||||
// paging::walk_tables();
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(modules_list) = *MODULE_RESPONSE
|
if let Some(modules_list) = *MODULE_RESPONSE
|
||||||
&& modules_list.modules()[0].path().ends_with("/userboot.bin")
|
&& modules_list.modules()[0].path().ends_with("/userboot.bin")
|
||||||
@ -201,40 +178,9 @@ unsafe extern "C" fn main() -> ! {
|
|||||||
let ub = modules_list.modules()[0];
|
let ub = modules_list.modules()[0];
|
||||||
log_info!("Found userboot: {} {}", ub.path(), ub.cmdline());
|
log_info!("Found userboot: {} {}", ub.path(), ub.cmdline());
|
||||||
|
|
||||||
//let start_addr = VirtAddr::from_ptr(ub.data() as *const [u8]);
|
let start_addr = VirtAddr::from_ptr(ub.data() as *const [u8]);
|
||||||
let start_addr = VirtAddr::from_ptr(usermode_fn as *const fn());
|
arch::startup::jump_to_usermode(VirtAddr::new(0xfffffff800000000), start_addr)
|
||||||
log_info!("Start address: 0x{:x}", start_addr);
|
} else {
|
||||||
|
panic!("Userboot not found, cannot boot!");
|
||||||
x86_64::registers::model_specific::Star::write(
|
|
||||||
SELECTORS.sel_user_code,
|
|
||||||
SELECTORS.sel_user_stack,
|
|
||||||
SELECTORS.sel_kernel_code,
|
|
||||||
SELECTORS.sel_kernel_stack,
|
|
||||||
)
|
|
||||||
.expect("fuck");
|
|
||||||
ltr(SELECTORS.sel_tss.index());
|
|
||||||
unsafe {
|
|
||||||
InterruptStackFrameValue::new(
|
|
||||||
VirtAddr::from_ptr(usermode_fn as *const fn()),
|
|
||||||
SELECTORS.sel_user_code,
|
|
||||||
RFlags::INTERRUPT_FLAG,
|
|
||||||
VirtAddr::new(0xffffffff80000000),
|
|
||||||
SELECTORS.sel_user_stack,
|
|
||||||
)
|
|
||||||
.iretq();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// - Map APIC
|
|
||||||
// - Create an interrupt stack frame, push it to stack, and iret to userboot
|
|
||||||
|
|
||||||
panic!("Finished boot, but cannot start init because processes not implemented!");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn usermode_fn() -> ! {
|
|
||||||
log_info!("In usermode!");
|
|
||||||
loop {
|
|
||||||
arch::asm::nop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user