From d5ca08e6475d8709c6b4ad24f386c0bd5bbf7665 Mon Sep 17 00:00:00 2001 From: shibedrill Date: Thu, 13 Mar 2025 13:09:45 -0400 Subject: [PATCH] Set up some stuff for syscalls? --- src/kernel/arch/x86_64/asm.rs | 5 +-- src/kernel/main.rs | 9 +++-- src/kernel/memory.rs | 23 ++++++++---- src/kernel/process.rs | 68 +++++++++++++++++++++++++++-------- src/kernel/syscall.rs | 26 ++++++++++++++ 5 files changed, 105 insertions(+), 26 deletions(-) create mode 100644 src/kernel/syscall.rs diff --git a/src/kernel/arch/x86_64/asm.rs b/src/kernel/arch/x86_64/asm.rs index d45b344..2390366 100644 --- a/src/kernel/arch/x86_64/asm.rs +++ b/src/kernel/arch/x86_64/asm.rs @@ -1,8 +1,9 @@ +#![allow(clippy::missing_safety_doc)] + use core::arch::asm; -#[allow(clippy::missing_safety_doc)] pub unsafe fn halt() { unsafe { asm!("hlt"); } -} +} \ No newline at end of file diff --git a/src/kernel/main.rs b/src/kernel/main.rs index 24b5c08..9f37111 100644 --- a/src/kernel/main.rs +++ b/src/kernel/main.rs @@ -10,6 +10,7 @@ mod panic; mod params; mod process; mod resources; +mod syscall; use crate::boot::*; use crate::log::*; @@ -28,7 +29,9 @@ unsafe extern "C" fn main() -> ! { // Set up some stuff based on kernel params if we get any if let Some(executable_file_response) = FILE_REQUEST.get_response() { - let kernel_parameters = get_kernel_params(limine::file::File::string(executable_file_response.file()).to_bytes()); + let kernel_parameters = get_kernel_params( + limine::file::File::string(executable_file_response.file()).to_bytes(), + ); // Set up logging level from params if let Some(level) = kernel_parameters.get("-loglevel") { @@ -51,7 +54,9 @@ unsafe extern "C" fn main() -> ! { LogLevel::Info, &format!( "Boot: Kernel cmdline: {}", - String::from_utf8_lossy(limine::file::File::string(executable_file_response.file()).to_bytes()) + String::from_utf8_lossy( + limine::file::File::string(executable_file_response.file()).to_bytes() + ) ), ); log( diff --git a/src/kernel/memory.rs b/src/kernel/memory.rs index 31c1536..963219b 100644 --- a/src/kernel/memory.rs +++ b/src/kernel/memory.rs @@ -1,6 +1,6 @@ #![allow(unused_imports)] -use flagset::flags; +use enumflags2::*; use core::alloc::{Allocator, Layout}; use talc::*; @@ -21,13 +21,22 @@ static ALLOCATOR: Talck, ClaimOnOom> = Talc::new(unsafe { pub struct MemoryRegion { start_address: usize, end_address: usize, - flags: MemoryRegionFlags, + flags: BitFlags, } -flags! { - pub enum MemoryRegionFlags: u8 { - READABLE, - WRITABLE, - EXECUTABLE, +impl MemoryRegion { + // TODO: Memory allocation and virtual addressing + #[allow(unused_variables)] + pub fn new(flags: BitFlags) -> Self { + todo!() } } + +#[bitflags] +#[repr(u8)] +#[derive(Clone, Copy)] +pub enum MemoryRegionFlags { + READABLE, + WRITABLE, + EXECUTABLE, +} diff --git a/src/kernel/process.rs b/src/kernel/process.rs index d45fc0c..90e6c01 100644 --- a/src/kernel/process.rs +++ b/src/kernel/process.rs @@ -1,12 +1,15 @@ #![allow(unused_imports)] +#![allow(dead_code)] -use enumflags2::{bitflags, make_bitflags, BitFlags}; +use enumflags2::{BitFlags, bitflags, make_bitflags}; +use crate::arch::current; use crate::memory::MemoryRegion; - +use crate::memory::MemoryRegionFlags; use crate::memory::alloc; use alloc::string::String; use alloc::vec::Vec; +use current::asm; #[allow(dead_code)] pub struct ProcessTable {} @@ -42,7 +45,7 @@ pub unsafe fn context_switch() -> ! { #[allow(unused_unsafe)] unsafe { loop { - crate::arch::current::asm::halt(); + asm::halt(); } } } @@ -60,20 +63,55 @@ pub enum ProcessState { #[derive(Copy, Clone)] pub enum ProcessCapabilities { // Process capabilities - ProcessEnum, // Enumerate running process IDs and names - ProcessRead, // Read information from a process struct - ProcessKill, // Kill any process - ProcessSpawn, // Create a new process - ProcessExec, // Replace self with new process image + ProcessEnum, // Enumerate running process IDs and names + ProcessRead, // Read information from a process struct + ProcessKill, // Kill any process + ProcessSpawn, // Create a new process + ProcessExec, // Replace self with new process image + ProcessSession, // Create and accept Session requests. // File system capabilities - FileEnum, // Enumerate directories and files - FileRead, // Read files - FileWrite, // Write to files + FileEnum, // Enumerate directories and files + FileRead, // Read files + FileWrite, // Write to files FilePermission, // Modify file permissions - FileCreate, // Create files - FileDelete, // Delete files - FileSystem, // Mount, unmount, and modify filesystems + FileCreate, // Create files + FileDelete, // Delete files + FileSystem, // Mount, unmount, and modify filesystems // Kernel config capabilities - KernelCfgRead, // Read kernel configurations + KernelCfgRead, // Read kernel configurations KernelCfgWrite, // Modify kernel configurations } + +// Interprocess communication system: +// Processes communicate through "sessions" which are mediated by the kernel. +// Sessions can only be opened if two processes both request a session with +// each other (mutual operation). Submitting a session request is a blocking +// system call that will return either once the other process accepts, or the +// kernel denies the request due to missing capability. +pub struct ProcessSession { + proc_id_a: u32, + proc_id_b: u32, + shared_mem: MemoryRegion, +} + +impl ProcessSession { + pub fn new(a: ProcessSessionRequest, b: ProcessSessionRequest) -> Self { + ProcessSession { + proc_id_a: a.proc_id, + proc_id_b: b.proc_id, + shared_mem: MemoryRegion::new( + MemoryRegionFlags::READABLE | MemoryRegionFlags::WRITABLE, + ), + } + } +} + +pub struct ProcessSessionRequest { + proc_id: u32, +} + +impl ProcessSessionRequest { + pub fn accept(self, b: ProcessSessionRequest) -> ProcessSession { + ProcessSession::new(self, b) + } +} diff --git a/src/kernel/syscall.rs b/src/kernel/syscall.rs new file mode 100644 index 0000000..9f3294a --- /dev/null +++ b/src/kernel/syscall.rs @@ -0,0 +1,26 @@ +#![allow(dead_code)] + +// FUCKING ADD CONST UNWRAP!!! +pub static KERNEL_VERSION_MAJOR: u8 = match u8::from_str_radix(env!("CARGO_PKG_VERSION_MAJOR"), 10) { + Ok(ver) => ver, + Err(_) => { panic!("Invalid version number ") }, +}; +pub static KERNEL_VERSION_MINOR: u8 = match u8::from_str_radix(env!("CARGO_PKG_VERSION_MINOR"), 10) { + Ok(ver) => ver, + Err(_) => { panic!("Invalid version number ") }, +}; +pub static KERNEL_VERSION_PATCH: u8 = match u8::from_str_radix(env!("CARGO_PKG_VERSION_PATCH"), 10) { + Ok(ver) => ver, + Err(_) => { panic!("Invalid version number ") }, +}; + +// TODO: Set up match statement that handles syscalls. +// All syscalls will be a function with the following signature: +// fn syscall(ctx: &mut Process, arg0: usize); +// The ctx variable should be a reference to the calling process, so we can +// modify its stored registers with return values. RAX is used to store the +// status number. + +// TODO: Figure out a way to make the ABI usable. The registers used to store +// system call results must be the same on the kernel side and the user side. +// As such, more work is needed to abstract this nicely. \ No newline at end of file