mirror of
https://github.com/XunilGroup/XunilOS.git
synced 2026-06-02 13:44:25 +02:00
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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user