diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index f5dbb60..6eeff65 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -32,7 +32,7 @@ bit_field = "0.10.1" lose-net-stack = { git = "https://github.com/byte-os/lose-net-stack", rev = "bb99460", features = ["log"]} # lose-net-stack = { path = "../../lose-net-stack", features = ["log"]} vfscore = { git = "https://github.com/Byte-OS/vfscore.git" } -async-recursion = "1.0.4" +async-recursion = "1.1.0" futures-lite = { version = "1.13.0", default-features = false, features=["alloc"] } # backtrace = { path = "../crates/backtrace" } hashbrown = "0.14" diff --git a/kernel/build.rs b/kernel/build.rs index ff2bff4..5f03f2d 100644 --- a/kernel/build.rs +++ b/kernel/build.rs @@ -11,11 +11,12 @@ macro_rules! display { // write module config to file. fn write_module_config(driver_list: Vec) { - let manifest_path = - PathBuf::from(env::var("OUT_DIR").expect("can't find manifest dir")); + let manifest_path = PathBuf::from(env::var("OUT_DIR").expect("can't find manifest dir")); let mut module_file_content = String::new(); driver_list.into_iter().for_each(|module| { - if module == "" { return }; + if module == "" { + return; + }; module_file_content.push_str(&format!("extern crate {};\n", module.replace("-", "_"))) }); fs::write(manifest_path.join("drivers.rs"), module_file_content) @@ -23,7 +24,8 @@ fn write_module_config(driver_list: Vec) { } fn main() { - let drivers = std::env::var("CARGO_CFG_DRIVER").unwrap_or(String::from("")) + let drivers = std::env::var("CARGO_CFG_DRIVER") + .unwrap_or(String::from("")) .split(",") .map(|x| x.trim().to_owned()) .collect(); diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index b0aee79..e0f039f 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -295,8 +295,8 @@ impl UserTaskContainer { args[0] as _, args[1] as _, args[2] as _, - args[3] as _, - args[4] as _, + args[3].into(), + args[4].into(), ) .await } diff --git a/kernel/src/syscall/socket.rs b/kernel/src/syscall/socket.rs index 1da3df1..063f7a7 100644 --- a/kernel/src/syscall/socket.rs +++ b/kernel/src/syscall/socket.rs @@ -375,29 +375,27 @@ impl UserTaskContainer { socket: usize, level: usize, optname: usize, - optval: *mut u32, - optlen: *mut u32, + optval: UserRef, + optlen: UserRef, ) -> SysResult { debug!("[task {}] sys_getsockopt @ socket: {:#x}, level: {:#x}, optname: {:#x}, optval: {:#x?}, optlen: {:#x?}", self.tid, socket, level, optname, optval, optlen); - unsafe { - let optval = optval.as_mut().unwrap(); - let _optlen = optlen.as_mut().unwrap(); - - match optname { - // send buffer - 0x7 => *optval = 32000, - // recv buffer - 0x8 => *optval = 32000, - 0x2 => *optval = 2000, - // getsockopt - 0x4 => return Err(LinuxError::EPERM), - _ => { - // *optval = 2000; - } + let optval = optval.get_mut(); + let _optlen = optlen.get_mut(); + + match optname { + // send buffer + 0x7 => *optval = 32000, + // recv buffer + 0x8 => *optval = 32000, + 0x2 => *optval = 2000, + // getsockopt + 0x4 => return Err(LinuxError::EPERM), + _ => { + // *optval = 2000; } - // debug!("ptr value: {:?}", optval); } + // debug!("ptr value: {:?}", optval); Ok(0) } diff --git a/kernel/src/syscall/task.rs b/kernel/src/syscall/task.rs index 9937adf..9843d04 100644 --- a/kernel/src/syscall/task.rs +++ b/kernel/src/syscall/task.rs @@ -186,15 +186,14 @@ pub fn cache_task_template(path: &str) -> Result<(), LinuxError> { Ok(()) } -#[async_recursion(?Send)] -pub async fn exec_with_process<'a>( +#[async_recursion(Sync)] +pub async fn exec_with_process( task: Arc, - path: &'a str, - args: Vec<&'a str>, - envp: Vec<&'a str>, + path: String, + args: Vec, + envp: Vec, ) -> Result, LinuxError> { // copy args, avoid free before pushing. - let args: Vec = args.into_iter().map(|x| String::from(x)).collect(); let path = String::from(path); let user_task = task.clone(); user_task.pcb.lock().memset.clear(); @@ -247,9 +246,9 @@ pub async fn exec_with_process<'a>( let elf = if let Ok(elf) = xmas_elf::ElfFile::new(&buffer) { elf } else { - let mut new_args = vec!["busybox", "sh"]; - args.iter().for_each(|x| new_args.push(x)); - return exec_with_process(task, "busybox", new_args, envp).await; + let mut new_args = vec!["busybox".to_string(), "sh".to_string()]; + args.iter().for_each(|x| new_args.push(x.clone())); + return exec_with_process(task, String::from("busybox"), new_args, envp).await; }; let elf_header = elf.header; @@ -270,10 +269,9 @@ pub async fn exec_with_process<'a>( if let Some(header) = header { if let Ok(SegmentData::Undefined(_data)) = header.get_data(&elf) { drop(frame_ppn); - let lib_path = "libc.so"; - let mut new_args = vec![lib_path, &path]; - args[1..].iter().for_each(|x| new_args.push(x)); - return exec_with_process(task, lib_path, new_args, envp).await; + let mut new_args = vec![String::from("libc.so")]; + new_args.extend(args); + return exec_with_process(task, new_args[0].clone(), new_args, envp).await; } } @@ -346,6 +344,7 @@ pub async fn exec_with_process<'a>( assert_eq!(&buffer[offset..offset + file_size], page_space); }); + // relocate data if base > 0 { relocated_arr.into_iter().for_each(|(addr, value)| unsafe { (addr as *mut usize).write_volatile(value); @@ -407,13 +406,13 @@ impl UserTaskContainer { let args = args .slice_until_valid(|x| x.is_valid()) .into_iter() - .map(|x| x.get_cstr().unwrap()) + .map(|x| x.get_cstr().unwrap().to_string()) .collect(); debug!("test1: envp: {:?}", envp); - let envp: Vec<&str> = envp + let envp: Vec = envp .slice_until_valid(|x| x.is_valid()) .into_iter() - .map(|x| x.get_cstr().unwrap()) + .map(|x| x.get_cstr().unwrap().to_string()) .collect(); debug!( "sys_execve @ filename: {} args: {:?}: envp: {:?}", @@ -430,7 +429,7 @@ impl UserTaskContainer { return Ok(0); } let _exec_file = FileItem::fs_open(filename, OpenFlags::O_RDONLY).map_err(from_vfs)?; - exec_with_process(self.task.clone(), filename, args, envp).await?; + exec_with_process(self.task.clone(), filename.to_string(), args, envp).await?; self.task.before_run(); Ok(0) } diff --git a/kernel/src/tasks/mod.rs b/kernel/src/tasks/mod.rs index 64c0bff..99d5d2a 100644 --- a/kernel/src/tasks/mod.rs +++ b/kernel/src/tasks/mod.rs @@ -1,3 +1,4 @@ +use alloc::string::String; use alloc::sync::Weak; use alloc::{sync::Arc, vec::Vec}; use devices::get_net_device; @@ -100,9 +101,14 @@ pub async fn add_user_task(filename: &str, args: Vec<&str>, envp: Vec<&str>) -> let task = UserTask::new(user_entry(), Weak::new(), initproc::USER_WORK_DIR); task.before_run(); - exec_with_process(task.clone(), filename, args, envp) - .await - .expect("can't add task to excutor"); + exec_with_process( + task.clone(), + String::from(filename), + args.into_iter().map(String::from).collect(), + envp.into_iter().map(String::from).collect(), + ) + .await + .expect("can't add task to excutor"); thread::spawn(task.clone()); curr_task.before_run(); diff --git a/kernel/src/tasks/task.rs b/kernel/src/tasks/task.rs index f5b3447..5ace496 100644 --- a/kernel/src/tasks/task.rs +++ b/kernel/src/tasks/task.rs @@ -12,7 +12,7 @@ use arch::{ {TrapFrame, TrapFrameArgs, PAGE_SIZE}, }; use executor::{ - task_id_alloc, thread, AsyncTask, DowncastTask, TaskFutureItem, TaskId, FUTURE_LIST, + task_id_alloc, thread, AsyncTask, DowncastTask, TaskId, FUTURE_LIST, }; use frame_allocator::{ceil_div, frame_alloc_much, FrameTracker}; use fs::File; @@ -49,13 +49,13 @@ impl Drop for KernelTask { } impl KernelTask { - pub fn new(future: impl Future + 'static) -> Arc { + pub fn new(future: impl Future + Send + 'static) -> Arc { let task_id = task_id_alloc(); let memset = vec![]; FUTURE_LIST .lock() - .insert(task_id, TaskFutureItem(Box::pin(kernel_entry(future)))); + .insert(task_id, Box::pin(kernel_entry(future))); Arc::new(Self { page_table: Arc::new(PageTableWrapper::alloc()), @@ -126,7 +126,7 @@ impl Drop for UserTask { impl UserTask { pub fn new( - future: impl Future + 'static, + future: impl Future + Send + 'static, parent: Weak, work_dir: &str, ) -> Arc { @@ -136,7 +136,7 @@ impl UserTask { FUTURE_LIST .lock() - .insert(task_id, TaskFutureItem(Box::pin(future))); + .insert(task_id, Box::pin(future)); let inner = ProcessControlBlock { memset, @@ -392,7 +392,10 @@ impl UserTask { } #[inline] - pub fn cow_fork(self: Arc, future: impl Future + 'static) -> Arc { + pub fn cow_fork( + self: Arc, + future: impl Future + Send + 'static, + ) -> Arc { // Give the frame_tracker in the memset a type. // it will contains the frame used for page mapping、 // mmap or text section. @@ -443,7 +446,10 @@ impl UserTask { } #[inline] - pub fn thread_clone(self: Arc, future: impl Future + 'static) -> Arc { + pub fn thread_clone( + self: Arc, + future: impl Future + Send + 'static, + ) -> Arc { // Give the frame_tracker in the memset a type. // it will contains the frame used for page mapping、 // mmap or text section. @@ -479,7 +485,7 @@ impl UserTask { FUTURE_LIST .lock() - .insert(task_id, TaskFutureItem(Box::pin(future))); + .insert(task_id, Box::pin(future)); thread::spawn(new_task.clone()); new_task diff --git a/kernel/src/user/entry.rs b/kernel/src/user/entry.rs index 428cc32..89b372c 100644 --- a/kernel/src/user/entry.rs +++ b/kernel/src/user/entry.rs @@ -1,4 +1,6 @@ +use alloc::boxed::Box; use arch::{kernel_page_table, TrapFrame, TrapFrameArgs}; +use async_recursion::async_recursion; use executor::{yield_now, AsyncTask}; use futures_lite::future; use hal::TimeVal; @@ -32,42 +34,42 @@ impl UserTaskContainer { } } - pub async fn entry_point(&mut self, cx_ref: &mut TrapFrame) { - let mut times = 0; - - let check_signal = async || { - loop { - let sig_mask = self.task.tcb.read().sigmask; - let signal = self - .task - .tcb - .read() - .signal - .clone() - .mask(sig_mask) - .try_get_signal(); - if let Some(signal) = signal { - debug!("mask: {:?}", sig_mask); - self.handle_signal(signal.clone()).await; - let mut tcb = self.task.tcb.write(); - tcb.signal.remove_signal(signal.clone()); - // check if it is a real time signal - if let Some(index) = signal.real_time_index() - && tcb.signal_queue[index] > 0 - { - tcb.signal.add_signal(signal.clone()); - tcb.signal_queue[index] -= 1; - } - } else { - break; + pub async fn check_signal(&self) { + loop { + let sig_mask = self.task.tcb.read().sigmask; + let signal = self + .task + .tcb + .read() + .signal + .clone() + .mask(sig_mask) + .try_get_signal(); + if let Some(signal) = signal { + debug!("mask: {:?}", sig_mask); + self.handle_signal(signal.clone()).await; + let mut tcb = self.task.tcb.write(); + tcb.signal.remove_signal(signal.clone()); + // check if it is a real time signal + if let Some(index) = signal.real_time_index() + && tcb.signal_queue[index] > 0 + { + tcb.signal.add_signal(signal.clone()); + tcb.signal_queue[index] -= 1; } + } else { + break; } - }; + } + } + + pub async fn entry_point(&mut self, cx_ref: &mut TrapFrame) { + let mut times: i32 = 0; loop { self.check_timer(); - check_signal().await; + self.check_signal().await; // check for task exit status. if let Some(exit_code) = self.check_thread_exit() { @@ -87,7 +89,7 @@ impl UserTaskContainer { let res = future::or(self.handle_syscall(cx_ref), async { loop { - check_signal().await; + self.check_signal().await; if let Some(_exit_code) = self.check_thread_exit() { return UserTaskControlFlow::Break; @@ -122,15 +124,10 @@ impl UserTaskContainer { } } +#[async_recursion(Sync)] pub async fn user_entry() { let task = current_user_task(); let cx_ref = task.force_cx_ref(); let tid = task.get_task_id(); - UserTaskContainer { - task, - tid, - store_frames: vec![], - } - .entry_point(cx_ref) - .await; + UserTaskContainer { task, tid }.entry_point(cx_ref).await; } diff --git a/kernel/src/user/mod.rs b/kernel/src/user/mod.rs index a6d5e51..dd903d4 100644 --- a/kernel/src/user/mod.rs +++ b/kernel/src/user/mod.rs @@ -1,12 +1,9 @@ -use core::pin::Pin; - use ::signal::SignalFlags; -use alloc::{boxed::Box, sync::Arc, vec::Vec}; +use alloc::sync::Arc; use arch::addr::VirtPage; use arch::{pagetable::MappingFlags, run_user_task, time::Time, TrapFrame, TrapFrameArgs}; use executor::{AsyncTask, TaskId}; use frame_allocator::frame_alloc; -use futures_lite::Future; use log::{debug, warn}; use crate::tasks::{MapTrack, MemType, UserTask}; @@ -22,10 +19,6 @@ pub mod socket_pair; pub struct UserTaskContainer { pub task: Arc, pub tid: TaskId, - pub store_frames: Vec<( - TrapFrame, - Pin>>, - )>, } /// Copy on write.