mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
riscv: copy-thread (#696)
This commit is contained in:
parent
dfe53cf087
commit
e8eab1ac82
@ -62,7 +62,7 @@ x86_64 = "=0.14.10"
|
||||
|
||||
# target为riscv64时,使用下面的依赖
|
||||
[target.'cfg(target_arch = "riscv64")'.dependencies]
|
||||
riscv = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/riscv.git", revision = "01fc40d", features = [ "s-mode" ] }
|
||||
riscv = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/riscv.git", revision = "bf771288c3", features = [ "s-mode" ] }
|
||||
sbi-rt = { version = "=0.0.3", features = ["legacy"] }
|
||||
|
||||
|
||||
|
@ -242,7 +242,7 @@ unsafe extern "C" fn _save_context() -> ! {
|
||||
|
||||
#[naked]
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn ret_from_exception() -> ! {
|
||||
pub unsafe extern "C" fn ret_from_exception() -> ! {
|
||||
asm!(
|
||||
concat!("
|
||||
ld s0, {off_status}(sp)
|
||||
|
@ -111,4 +111,49 @@ impl TrapFrame {
|
||||
pub fn is_from_user(&self) -> bool {
|
||||
self.status.spp() == riscv::register::sstatus::SPP::User
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
epc: 0,
|
||||
ra: 0,
|
||||
sp: 0,
|
||||
gp: 0,
|
||||
tp: 0,
|
||||
t0: 0,
|
||||
t1: 0,
|
||||
t2: 0,
|
||||
s0: 0,
|
||||
s1: 0,
|
||||
a0: 0,
|
||||
a1: 0,
|
||||
a2: 0,
|
||||
a3: 0,
|
||||
a4: 0,
|
||||
a5: 0,
|
||||
a6: 0,
|
||||
a7: 0,
|
||||
s2: 0,
|
||||
s3: 0,
|
||||
s4: 0,
|
||||
s5: 0,
|
||||
s6: 0,
|
||||
s7: 0,
|
||||
s8: 0,
|
||||
s9: 0,
|
||||
s10: 0,
|
||||
s11: 0,
|
||||
t3: 0,
|
||||
t4: 0,
|
||||
t5: 0,
|
||||
t6: 0,
|
||||
status: unsafe { core::mem::zeroed() },
|
||||
badaddr: 0,
|
||||
cause: unsafe { core::mem::zeroed() },
|
||||
origin_a0: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_return_value(&mut self, value: usize) {
|
||||
self.a0 = value;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,14 @@
|
||||
use alloc::sync::Arc;
|
||||
use riscv::register::sstatus::SPP;
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::process::{
|
||||
fork::CloneFlags,
|
||||
kthread::{KernelThreadCreateInfo, KernelThreadMechanism},
|
||||
Pid,
|
||||
use crate::{
|
||||
arch::interrupt::TrapFrame,
|
||||
process::{
|
||||
fork::CloneFlags,
|
||||
kthread::{KernelThreadCreateInfo, KernelThreadMechanism},
|
||||
Pid, ProcessManager,
|
||||
},
|
||||
};
|
||||
|
||||
impl KernelThreadMechanism {
|
||||
@ -13,11 +17,35 @@ impl KernelThreadMechanism {
|
||||
/// ## 返回值
|
||||
///
|
||||
/// 返回创建的内核线程的pid
|
||||
#[inline(never)]
|
||||
pub fn __inner_create(
|
||||
info: &Arc<KernelThreadCreateInfo>,
|
||||
clone_flags: CloneFlags,
|
||||
) -> Result<Pid, SystemError> {
|
||||
unimplemented!("KernelThreadMechanism::__inner_create")
|
||||
// WARNING: If create failed, we must drop the info manually or it will cause memory leak. (refcount will not decrease when create failed)
|
||||
let create_info: *const KernelThreadCreateInfo =
|
||||
KernelThreadCreateInfo::generate_unsafe_arc_ptr(info.clone());
|
||||
|
||||
let mut frame = TrapFrame::new();
|
||||
frame.a0 = create_info as usize;
|
||||
|
||||
// 使能中断
|
||||
frame.status.update_sie(true);
|
||||
frame.status.update_spp(SPP::Supervisor);
|
||||
|
||||
frame.ra = kernel_thread_bootstrap_stage1 as usize;
|
||||
|
||||
// fork失败的话,子线程不会执行。否则将导致内存安全问题。
|
||||
let pid = ProcessManager::fork(&frame, clone_flags).map_err(|e| {
|
||||
unsafe { KernelThreadCreateInfo::parse_unsafe_arc_ptr(create_info) };
|
||||
e
|
||||
})?;
|
||||
|
||||
ProcessManager::find(pid)
|
||||
.unwrap()
|
||||
.set_name(info.name().clone());
|
||||
|
||||
return Ok(pid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,16 +13,20 @@ use kdepends::memoffset::offset_of;
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
arch::CurrentIrqArch,
|
||||
arch::{
|
||||
interrupt::entry::ret_from_exception, process::kthread::kernel_thread_bootstrap_stage1,
|
||||
CurrentIrqArch,
|
||||
},
|
||||
exception::InterruptArch,
|
||||
kerror,
|
||||
libs::spinlock::SpinLockGuard,
|
||||
mm::VirtAddr,
|
||||
process::{
|
||||
fork::KernelCloneArgs, KernelStack, ProcessControlBlock, ProcessManager,
|
||||
PROCESS_SWITCH_RESULT,
|
||||
fork::{CloneFlags, KernelCloneArgs},
|
||||
KernelStack, ProcessControlBlock, ProcessFlags, ProcessManager, PROCESS_SWITCH_RESULT,
|
||||
},
|
||||
smp::cpu::ProcessorId,
|
||||
syscall::Syscall,
|
||||
};
|
||||
|
||||
use super::{
|
||||
@ -65,7 +69,52 @@ impl ProcessManager {
|
||||
clone_args: KernelCloneArgs,
|
||||
current_trapframe: &TrapFrame,
|
||||
) -> Result<(), SystemError> {
|
||||
unimplemented!("ProcessManager::copy_thread")
|
||||
let clone_flags = clone_args.flags;
|
||||
let mut child_trapframe = *current_trapframe;
|
||||
|
||||
// 子进程的返回值为0
|
||||
child_trapframe.set_return_value(0);
|
||||
|
||||
// 设置子进程的栈基址(开始执行中断返回流程时的栈基址)
|
||||
let mut new_arch_guard = unsafe { new_pcb.arch_info() };
|
||||
let kernel_stack_guard = new_pcb.kernel_stack();
|
||||
let trap_frame_vaddr: VirtAddr =
|
||||
kernel_stack_guard.stack_max_address() - core::mem::size_of::<TrapFrame>();
|
||||
new_arch_guard.set_stack(trap_frame_vaddr);
|
||||
|
||||
// 拷贝栈帧
|
||||
unsafe {
|
||||
let usp = clone_args.stack;
|
||||
if usp != 0 {
|
||||
child_trapframe.sp = usp;
|
||||
}
|
||||
let trap_frame_ptr = trap_frame_vaddr.data() as *mut TrapFrame;
|
||||
*trap_frame_ptr = child_trapframe;
|
||||
}
|
||||
|
||||
// copy arch info
|
||||
|
||||
let current_arch_guard = current_pcb.arch_info_irqsave();
|
||||
// 拷贝浮点寄存器的状态
|
||||
new_arch_guard.fp_state = current_arch_guard.fp_state;
|
||||
|
||||
drop(current_arch_guard);
|
||||
|
||||
// 设置返回地址(子进程开始执行的指令地址)
|
||||
if new_pcb.flags().contains(ProcessFlags::KTHREAD) {
|
||||
let kthread_bootstrap_stage1_func_addr = kernel_thread_bootstrap_stage1 as usize;
|
||||
new_arch_guard.ra = kthread_bootstrap_stage1_func_addr;
|
||||
} else {
|
||||
new_arch_guard.ra = ret_from_exception as usize;
|
||||
}
|
||||
|
||||
// 设置tls
|
||||
if clone_flags.contains(CloneFlags::CLONE_SETTLS) {
|
||||
drop(new_arch_guard);
|
||||
todo!("set tls");
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
/// 切换进程
|
||||
@ -221,7 +270,7 @@ impl ProcessControlBlock {
|
||||
}
|
||||
|
||||
/// PCB中与架构相关的信息
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[allow(dead_code)]
|
||||
#[repr(C)]
|
||||
pub struct ArchPCBInfo {
|
||||
@ -277,12 +326,16 @@ impl ArchPCBInfo {
|
||||
}
|
||||
// ### 从另一个ArchPCBInfo处clone,但是保留部分字段不变
|
||||
pub fn clone_from(&mut self, from: &Self) {
|
||||
unimplemented!("ArchPCBInfo::clone_from")
|
||||
*self = from.clone();
|
||||
}
|
||||
|
||||
pub fn set_stack(&mut self, stack: VirtAddr) {
|
||||
self.ksp = stack.data();
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct FpDExtState {
|
||||
f: [u64; 32],
|
||||
fcsr: u32,
|
||||
|
Loading…
x
Reference in New Issue
Block a user