Skip to content

Commit

Permalink
prepare kernel to use it as common monolithic kernel
Browse files Browse the repository at this point in the history
- currently, only x86 is supported
- add system call interface and system call table, which includes
  function pointer to the implementations
- save GS register during a context switch
- swap GS register, if the user spaces is interrupted
- introduce privilege level dor the the user-space
- create for every process an own page table
  • Loading branch information
stlankes committed Feb 16, 2024
1 parent aa01ba5 commit a3362a6
Show file tree
Hide file tree
Showing 25 changed files with 761 additions and 128 deletions.
69 changes: 38 additions & 31 deletions src/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,64 +2,70 @@
cfg_if::cfg_if! {
if #[cfg(target_arch = "aarch64")] {
pub mod aarch64;
pub use self::aarch64::*;
pub(crate) mod aarch64;
pub(crate) use self::aarch64::*;

#[cfg(target_os = "none")]
pub use self::aarch64::kernel::boot_processor_init;
pub use self::aarch64::kernel::core_local;
pub use self::aarch64::kernel::interrupts;
pub use self::aarch64::kernel::interrupts::wakeup_core;
pub(crate) use self::aarch64::kernel::boot_processor_init;
pub(crate) use self::aarch64::kernel::core_local;
pub(crate) use self::aarch64::kernel::interrupts;
pub(crate) use self::aarch64::kernel::interrupts::wakeup_core;
#[cfg(feature = "pci")]
pub use self::aarch64::kernel::pci;
pub use self::aarch64::kernel::processor;
pub use self::aarch64::kernel::processor::set_oneshot_timer;
pub use self::aarch64::kernel::scheduler;
pub use self::aarch64::kernel::switch;
pub(crate) use self::aarch64::kernel::pci;
pub(crate) use self::aarch64::kernel::processor;
pub(crate) use self::aarch64::kernel::processor::set_oneshot_timer;
pub(crate) use self::aarch64::kernel::scheduler;
pub(crate) use self::aarch64::kernel::switch;
#[cfg(feature = "smp")]
pub use self::aarch64::kernel::application_processor_init;
pub use self::aarch64::kernel::{
pub(crate) use self::aarch64::kernel::application_processor_init;
pub(crate) use self::aarch64::kernel::{
boot_application_processors,
get_processor_count,
message_output_init,
output_message_buf,
};
pub use self::aarch64::mm::paging::{BasePageSize, PageSize};
} else if #[cfg(target_arch = "x86_64")] {
pub mod x86_64;
pub use self::x86_64::*;
pub(crate) mod x86_64;
pub(crate) use self::x86_64::*;

pub use self::x86_64::kernel::apic::{
pub(crate) use self::x86_64::kernel::apic::{
set_oneshot_timer,
wakeup_core,
};
#[cfg(all(target_os = "none", feature = "smp"))]
pub use self::x86_64::kernel::application_processor_init;
pub use self::x86_64::kernel::core_local;
pub use self::x86_64::kernel::gdt::set_current_kernel_stack;
pub use self::x86_64::kernel::interrupts;
pub(crate) use self::x86_64::kernel::application_processor_init;
pub(crate) use self::x86_64::kernel::core_local;
pub(crate) use self::x86_64::kernel::gdt::set_current_kernel_stack;
pub(crate) use self::x86_64::kernel::interrupts;
#[cfg(feature = "pci")]
pub use self::x86_64::kernel::pci;
pub use self::x86_64::kernel::processor;
pub use self::x86_64::kernel::scheduler;
pub use self::x86_64::kernel::switch;
pub(crate) use self::x86_64::kernel::pci;
pub(crate) use self::x86_64::kernel::processor;
pub(crate) use self::x86_64::kernel::scheduler;
pub(crate) use self::x86_64::kernel::switch;
#[cfg(target_os = "none")]
pub use self::x86_64::kernel::{
pub(crate) use self::x86_64::kernel::{
boot_application_processors,
boot_processor_init,
};
pub use self::x86_64::kernel::{
pub(crate) use self::x86_64::kernel::{
get_processor_count,
message_output_init,
output_message_buf,
};
pub use self::x86_64::mm::paging::{BasePageSize, PageSize};
#[cfg(feature = "common-os")]
pub use self::x86_64::mm::create_new_root_page_table;
#[cfg(feature = "common-os")]
pub use self::x86_64::kernel::{load_application, jump_to_user_land};
} else if #[cfg(target_arch = "riscv64")] {
pub mod riscv64;
pub use self::riscv64::*;
pub(crate) mod riscv64;
pub(crate) use self::riscv64::*;

#[cfg(feature = "smp")]
pub use self::riscv64::kernel::application_processor_init;
pub use self::riscv64::kernel::processor::{self, set_oneshot_timer, wakeup_core};
pub use self::riscv64::kernel::{
pub(crate) use self::riscv64::kernel::application_processor_init;
pub(crate) use self::riscv64::kernel::processor::{self, set_oneshot_timer, wakeup_core};
pub(crate) use self::riscv64::kernel::{
boot_application_processors,
boot_processor_init,
core_local,
Expand All @@ -70,5 +76,6 @@ cfg_if::cfg_if! {
scheduler,
switch,
};
pub use self::riscv64::mm::paging::{BasePageSize, PageSize};
}
}
11 changes: 9 additions & 2 deletions src/arch/x86_64/kernel/apic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use crate::arch::x86_64::mm::paging::{
BasePageSize, PageSize, PageTableEntryFlags, PageTableEntryFlagsExt,
};
use crate::arch::x86_64::mm::{paging, virtualmem, PhysAddr, VirtAddr};
use crate::arch::x86_64::swapgs;
use crate::config::*;
use crate::scheduler::CoreId;
use crate::{arch, env, mm, scheduler};
Expand Down Expand Up @@ -199,16 +200,19 @@ impl fmt::Display for IoApicRecord {
}

#[cfg(feature = "smp")]
extern "x86-interrupt" fn tlb_flush_handler(_stack_frame: interrupts::ExceptionStackFrame) {
extern "x86-interrupt" fn tlb_flush_handler(stack_frame: interrupts::ExceptionStackFrame) {
swapgs(&stack_frame);
debug!("Received TLB Flush Interrupt");
increment_irq_counter(TLB_FLUSH_INTERRUPT_NUMBER);
unsafe {
cr3_write(cr3());
}
eoi();
swapgs(&stack_frame);
}

extern "x86-interrupt" fn error_interrupt_handler(stack_frame: interrupts::ExceptionStackFrame) {
swapgs(&stack_frame);
error!("APIC LVT Error Interrupt");
error!("ESR: {:#X}", local_apic_read(IA32_X2APIC_ESR));
error!("{:#?}", stack_frame);
Expand All @@ -217,12 +221,14 @@ extern "x86-interrupt" fn error_interrupt_handler(stack_frame: interrupts::Excep
}

extern "x86-interrupt" fn spurious_interrupt_handler(stack_frame: interrupts::ExceptionStackFrame) {
swapgs(&stack_frame);
error!("Spurious Interrupt: {:#?}", stack_frame);
scheduler::abort();
}

#[cfg(feature = "smp")]
extern "x86-interrupt" fn wakeup_handler(_stack_frame: interrupts::ExceptionStackFrame) {
extern "x86-interrupt" fn wakeup_handler(stack_frame: interrupts::ExceptionStackFrame) {
swapgs(&stack_frame);
use crate::scheduler::PerCoreSchedulerExt;

debug!("Received Wakeup Interrupt");
Expand All @@ -233,6 +239,7 @@ extern "x86-interrupt" fn wakeup_handler(_stack_frame: interrupts::ExceptionStac
if core_scheduler.is_scheduling() {
core_scheduler.reschedule();
}
swapgs(&stack_frame);
}

#[inline]
Expand Down
19 changes: 18 additions & 1 deletion src/arch/x86_64/kernel/gdt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use core::sync::atomic::Ordering;

use x86_64::instructions::tables;
use x86_64::registers::segmentation::{Segment, CS, DS, ES, SS};
#[cfg(feature = "common-os")]
use x86_64::structures::gdt::DescriptorFlags;
use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable};
use x86_64::structures::tss::TaskStateSegment;
use x86_64::VirtAddr;
Expand All @@ -15,9 +17,16 @@ use crate::arch::x86_64::mm::paging::{BasePageSize, PageSize};
use crate::config::KERNEL_STACK_SIZE;

pub fn add_current_core() {
let gdt = Box::leak(Box::new(GlobalDescriptorTable::new()));
let gdt: &mut GlobalDescriptorTable = Box::leak(Box::new(GlobalDescriptorTable::new()));
let kernel_code_selector = gdt.add_entry(Descriptor::kernel_code_segment());
let kernel_data_selector = gdt.add_entry(Descriptor::kernel_data_segment());
#[cfg(feature = "common-os")]
{
let _user_code32_selector =
gdt.add_entry(Descriptor::UserSegment(DescriptorFlags::USER_CODE32.bits()));
let _user_data64_selector = gdt.add_entry(Descriptor::user_data_segment());
let _user_code64_selector = gdt.add_entry(Descriptor::user_code_segment());
}

// Dynamically allocate memory for a Task-State Segment (TSS) for this core.
let tss = Box::leak(Box::new(TaskStateSegment::new()));
Expand Down Expand Up @@ -60,5 +69,13 @@ pub fn add_current_core() {
}

pub extern "C" fn set_current_kernel_stack() {
#[cfg(feature = "common-os")]
unsafe {
let root = crate::scheduler::get_root_page_table();
if root != x86::controlregs::cr3().try_into().unwrap() {
x86::controlregs::cr3_write(root.try_into().unwrap());
}
}

core_scheduler().set_current_kernel_stack();
}
Loading

0 comments on commit a3362a6

Please sign in to comment.