Increase kernel stack size to 2mb, move from cooperative to timer

preemption based scheduling, add correct save_lock on aarch64, add
simple IPC (read, write, manage), and simple and unsecure SHM, add
per-process kernel stacks, add copy_cstr_to_user, always use run_next
for aarch64, remove primitives from the kernel
This commit is contained in:
csd4ni3l
2026-05-26 09:53:59 +02:00
parent 7070b53355
commit 6ebc6ada09
37 changed files with 1065 additions and 475 deletions
+142 -6
View File
@@ -1,7 +1,10 @@
use core::ptr::null;
use core::{
ptr::null,
sync::atomic::{AtomicU64, Ordering},
};
#[cfg(target_arch = "x86_64")]
use crate::arch::x86_64::paging::create_and_map_multiple_pages;
use crate::arch::x86_64::{interrupts, paging::create_and_map_multiple_pages};
#[allow(unused_imports)]
use crate::driver::elf::{
header::{
@@ -13,11 +16,19 @@ use crate::driver::elf::{
#[cfg(target_arch = "aarch64")]
use crate::arch::aarch64::paging::{
AArchPageTable, create_and_map_multiple_pages, user_data_flags,
AArchPageTable, create_and_map_multiple_pages, kernel_data_flags, user_data_flags,
};
use crate::{
arch::arch::KERNEL_MAPPER,
mm::address_space::AddressSpace,
println,
task::{context::UserContext, scheduler::SCHEDULER},
};
use crate::{mm::address_space::AddressSpace, println, task::scheduler::SCHEDULER};
#[cfg(target_arch = "x86_64")]
use x86_64::structures::paging::{OffsetPageTable, PageTableFlags};
use x86_64::{
registers::control::{Cr3, Cr3Flags},
structures::paging::{OffsetPageTable, PageTableFlags, PhysFrame, Size4KiB},
};
#[cfg(target_arch = "aarch64")]
type PageTable = AArchPageTable;
@@ -25,6 +36,29 @@ type PageTable = AArchPageTable;
#[cfg(target_arch = "x86_64")]
type PageTable<'a> = OffsetPageTable<'a>;
static mut NEXT_KERNEL_STACK_ADDR: AtomicU64 = AtomicU64::new(0xFFFF_FFFF_7000_0000);
pub fn next_kstack(mapper: &mut PageTable) -> u64 {
const PAGES: u64 = 2048;
#[allow(static_mut_refs)]
let addr = unsafe { NEXT_KERNEL_STACK_ADDR.fetch_add(PAGES * 4096, Ordering::Relaxed) };
#[cfg(target_arch = "aarch64")]
create_and_map_multiple_pages(mapper, PAGES, addr, kernel_data_flags());
#[cfg(target_arch = "x86_64")]
create_and_map_multiple_pages(
mapper,
PAGES,
addr,
PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
);
assert!(addr & 0xF == 0, "kernel stack isn't 16 byte aligned");
addr + PAGES * 4096
}
pub fn validate_elf(elf_header: &Elf64Ehdr, elf_len: usize) -> bool {
#[cfg(target_arch = "x86_64")]
let required_machine = EM_X86_64;
@@ -73,20 +107,54 @@ pub fn load_file(mapper: &mut PageTable, elf_bytes: &[u8]) -> (*const u8, u64) {
}
pub fn run_elf(file_bytes: &[u8], should_swapgs: bool, switch_to: bool) {
#[cfg(target_arch = "aarch64")]
unsafe {
core::arch::asm!("msr daifset, #2")
};
#[cfg(target_arch = "x86_64")]
{
use x86_64::instructions::interrupts;
interrupts::disable();
}
let stack_base: u64 = 0x0000_7fff_0000_0000;
let page_count = 4096; // 16 mib
let page_size = 0x1000u64;
let stack_top = stack_base + (page_count as u64 * page_size);
if let Some(mut address_space) = AddressSpace::new() {
#[cfg(target_arch = "aarch64")]
let previous_pt_ptr: u64;
#[cfg(target_arch = "aarch64")]
unsafe {
core::arch::asm!("mrs {}, ttbr0_el1", out(reg) previous_pt_ptr)
};
#[cfg(target_arch = "x86_64")]
let previous_pt: (PhysFrame<Size4KiB>, Cr3Flags);
#[cfg(target_arch = "x86_64")]
{
use x86_64::registers::control::Cr3;
previous_pt = Cr3::read();
}
address_space.use_address_space();
let (entry_point, heap_base) = load_file(&mut address_space.mapper, file_bytes);
println!("Entry point: {:?}", entry_point);
#[allow(static_mut_refs)]
let process_pid = SCHEDULER
.spawn_process(entry_point as u64, stack_top, heap_base)
.spawn_process(
entry_point as u64,
stack_top,
next_kstack(unsafe { KERNEL_MAPPER.get_mut().as_mut().unwrap() }),
heap_base,
)
.unwrap();
#[cfg(target_arch = "aarch64")]
@@ -109,8 +177,76 @@ pub fn run_elf(file_bytes: &[u8], should_swapgs: bool, switch_to: bool) {
process.address_space = Some(address_space)
});
#[cfg(target_arch = "aarch64")]
SCHEDULER.with_process(process_pid, |process| {
process.saved_ctx = Some(UserContext {
x0: 0,
x1: 0,
x2: 0,
x3: 0,
x4: 0,
x5: 0,
x6: 0,
x7: 0,
x8: 0,
x9: 0,
x10: 0,
x11: 0,
x12: 0,
x13: 0,
x14: 0,
x15: 0,
x16: 0,
x17: 0,
x18: 0,
x19: 0,
x20: 0,
x21: 0,
x22: 0,
x23: 0,
x24: 0,
x25: 0,
x26: 0,
x27: 0,
x28: 0,
x29: 0,
x30: 0,
elr_el1: entry_point as u64,
spsr_el1: 0,
esr_el1: 0,
far_el1: 0,
sp_el0: process.stack_top,
sp_el1: process.kernel_stack_top,
_pad1: 0,
});
});
if switch_to {
#[cfg(target_arch = "aarch64")]
unsafe {
core::arch::asm!("msr daifset, #2")
};
SCHEDULER.switch_to(process_pid, should_swapgs);
} else {
#[cfg(target_arch = "aarch64")]
unsafe {
core::arch::asm!(
"msr ttbr0_el1, {root}",
"dsb ishst",
"tlbi vmalle1is",
"dsb ish",
"isb",
root = in(reg) previous_pt_ptr
);
}
#[cfg(target_arch = "x86_64")]
unsafe {
use x86_64::instructions::interrupts;
Cr3::write(previous_pt.0, previous_pt.1);
interrupts::enable();
};
}
} else {
return;