This commit is contained in:
parent
2c7b850b52
commit
6df1c6f48c
3 changed files with 45 additions and 3 deletions
|
@ -1,5 +1,5 @@
|
|||
[workspace]
|
||||
resolver = "2"
|
||||
resolver = "3"
|
||||
members = ["lib/acpica-rs", "lib/kernel-common", "loader", "kernel", "init"]
|
||||
|
||||
[profile.release]
|
||||
|
|
|
@ -17,6 +17,7 @@ use super::{locks::Spinlock, scheduler::SCHEDULER, task::create_task};
|
|||
|
||||
pub struct Process {
|
||||
pub pid: usize,
|
||||
pub uid: usize,
|
||||
pub address_space: AddressSpace,
|
||||
pub binary: Option<&'static [u8]>,
|
||||
pub num_tasks: usize,
|
||||
|
@ -25,6 +26,7 @@ pub struct Process {
|
|||
static KERNEL_PROCESS: Spinlock<LazyCell<Arc<Spinlock<Process>>>> = Spinlock::new(LazyCell::new(|| {
|
||||
let process = Process {
|
||||
pid: 0,
|
||||
uid: 0,
|
||||
address_space: AddressSpace {
|
||||
is_kernel: true,
|
||||
pml4: OnceCell::new(),
|
||||
|
@ -46,6 +48,7 @@ pub fn create_process(binary: Option<&'static [u8]>) -> Arc<Spinlock<Process>> {
|
|||
let pid = NEXT_PID.fetch_add(1, Ordering::SeqCst);
|
||||
let mut process = Process {
|
||||
pid,
|
||||
uid: 0,
|
||||
address_space: AddressSpace {
|
||||
is_kernel: false,
|
||||
pml4: OnceCell::new(),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use core::{error::Error, ptr::copy};
|
||||
|
||||
use acpica_rs::{AcpiEnterSleepState, AcpiEnterSleepStatePrep, AcpiReset};
|
||||
use alloc::{boxed::Box, string::String, vec, vec::Vec};
|
||||
use log::{debug, trace};
|
||||
|
||||
|
@ -8,7 +9,10 @@ use crate::cpu::{
|
|||
paging::USER_END,
|
||||
};
|
||||
|
||||
use super::task::{terminate_current_task, with_current_task};
|
||||
use super::{
|
||||
sync::increase_lock_count,
|
||||
task::{terminate_current_task, with_current_task},
|
||||
};
|
||||
|
||||
struct SyscallArgs {
|
||||
arg1: usize,
|
||||
|
@ -22,7 +26,7 @@ struct Syscall {
|
|||
num_args: usize,
|
||||
}
|
||||
|
||||
const SYSCALL_TABLE: [Syscall; 4] = [
|
||||
const SYSCALL_TABLE: [Syscall; 5] = [
|
||||
Syscall {
|
||||
func: syscall_get_kernel_version,
|
||||
num_args: 0,
|
||||
|
@ -33,6 +37,7 @@ const SYSCALL_TABLE: [Syscall; 4] = [
|
|||
num_args: 2,
|
||||
},
|
||||
Syscall { func: syscall_get_pid, num_args: 0 },
|
||||
Syscall { func: syscall_shutdown, num_args: 1 },
|
||||
];
|
||||
|
||||
fn copy_from_user(start: u64, size: usize) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||
|
@ -61,6 +66,19 @@ fn copy_from_user(start: u64, size: usize) -> Result<Vec<u8>, Box<dyn Error>> {
|
|||
disable_user_memory_access();
|
||||
Ok(buffer)
|
||||
}
|
||||
fn require_root() -> Result<(), Box<dyn Error>> {
|
||||
let mut error = false;
|
||||
with_current_task(|current_task| {
|
||||
let process = current_task.process.lock();
|
||||
if process.uid != 0 {
|
||||
error = true;
|
||||
}
|
||||
});
|
||||
if error {
|
||||
return Err("Permission denied".into());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn syscall_get_kernel_version(_args: SyscallArgs) -> Result<usize, Box<dyn Error>> {
|
||||
Ok(0)
|
||||
}
|
||||
|
@ -69,6 +87,7 @@ fn syscall_exit(_args: SyscallArgs) -> Result<usize, Box<dyn Error>> {
|
|||
terminate_current_task();
|
||||
}
|
||||
fn syscall_debug_print(args: SyscallArgs) -> Result<usize, Box<dyn Error>> {
|
||||
require_root()?;
|
||||
let data = copy_from_user(args.arg1 as u64, args.arg2)?;
|
||||
let string = String::from_utf8(data)?;
|
||||
trace!("{}", string);
|
||||
|
@ -79,6 +98,26 @@ fn syscall_get_pid(_args: SyscallArgs) -> Result<usize, Box<dyn Error>> {
|
|||
with_current_task(|current_task| pid = current_task.process.lock().pid);
|
||||
Ok(pid)
|
||||
}
|
||||
fn syscall_shutdown(args: SyscallArgs) -> Result<usize, Box<dyn Error>> {
|
||||
require_root()?;
|
||||
// TODO: Stop all processes and sync devices first
|
||||
if args.arg1 == 0 {
|
||||
unsafe {
|
||||
AcpiEnterSleepStatePrep(5);
|
||||
}
|
||||
increase_lock_count();
|
||||
unsafe {
|
||||
AcpiEnterSleepState(5);
|
||||
}
|
||||
} else if args.arg1 == 1 {
|
||||
unsafe {
|
||||
AcpiReset();
|
||||
}
|
||||
} else {
|
||||
return Err("Invalid syscall argument".into());
|
||||
}
|
||||
panic!("Shutting down failed");
|
||||
}
|
||||
#[no_mangle]
|
||||
extern "C" fn syscall_handler(syscall: u64, arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) -> u64 {
|
||||
if syscall as usize >= SYSCALL_TABLE.len() {
|
||||
|
|
Loading…
Add table
Reference in a new issue