mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 11:16:47 +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为riscv64时,使用下面的依赖
|
||||||
[target.'cfg(target_arch = "riscv64")'.dependencies]
|
[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"] }
|
sbi-rt = { version = "=0.0.3", features = ["legacy"] }
|
||||||
|
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ unsafe extern "C" fn _save_context() -> ! {
|
|||||||
|
|
||||||
#[naked]
|
#[naked]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn ret_from_exception() -> ! {
|
pub unsafe extern "C" fn ret_from_exception() -> ! {
|
||||||
asm!(
|
asm!(
|
||||||
concat!("
|
concat!("
|
||||||
ld s0, {off_status}(sp)
|
ld s0, {off_status}(sp)
|
||||||
|
@ -111,4 +111,49 @@ impl TrapFrame {
|
|||||||
pub fn is_from_user(&self) -> bool {
|
pub fn is_from_user(&self) -> bool {
|
||||||
self.status.spp() == riscv::register::sstatus::SPP::User
|
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 alloc::sync::Arc;
|
||||||
|
use riscv::register::sstatus::SPP;
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use crate::process::{
|
use crate::{
|
||||||
fork::CloneFlags,
|
arch::interrupt::TrapFrame,
|
||||||
kthread::{KernelThreadCreateInfo, KernelThreadMechanism},
|
process::{
|
||||||
Pid,
|
fork::CloneFlags,
|
||||||
|
kthread::{KernelThreadCreateInfo, KernelThreadMechanism},
|
||||||
|
Pid, ProcessManager,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl KernelThreadMechanism {
|
impl KernelThreadMechanism {
|
||||||
@ -13,11 +17,35 @@ impl KernelThreadMechanism {
|
|||||||
/// ## 返回值
|
/// ## 返回值
|
||||||
///
|
///
|
||||||
/// 返回创建的内核线程的pid
|
/// 返回创建的内核线程的pid
|
||||||
|
#[inline(never)]
|
||||||
pub fn __inner_create(
|
pub fn __inner_create(
|
||||||
info: &Arc<KernelThreadCreateInfo>,
|
info: &Arc<KernelThreadCreateInfo>,
|
||||||
clone_flags: CloneFlags,
|
clone_flags: CloneFlags,
|
||||||
) -> Result<Pid, SystemError> {
|
) -> 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 system_error::SystemError;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::CurrentIrqArch,
|
arch::{
|
||||||
|
interrupt::entry::ret_from_exception, process::kthread::kernel_thread_bootstrap_stage1,
|
||||||
|
CurrentIrqArch,
|
||||||
|
},
|
||||||
exception::InterruptArch,
|
exception::InterruptArch,
|
||||||
kerror,
|
kerror,
|
||||||
libs::spinlock::SpinLockGuard,
|
libs::spinlock::SpinLockGuard,
|
||||||
mm::VirtAddr,
|
mm::VirtAddr,
|
||||||
process::{
|
process::{
|
||||||
fork::KernelCloneArgs, KernelStack, ProcessControlBlock, ProcessManager,
|
fork::{CloneFlags, KernelCloneArgs},
|
||||||
PROCESS_SWITCH_RESULT,
|
KernelStack, ProcessControlBlock, ProcessFlags, ProcessManager, PROCESS_SWITCH_RESULT,
|
||||||
},
|
},
|
||||||
smp::cpu::ProcessorId,
|
smp::cpu::ProcessorId,
|
||||||
|
syscall::Syscall,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -65,7 +69,52 @@ impl ProcessManager {
|
|||||||
clone_args: KernelCloneArgs,
|
clone_args: KernelCloneArgs,
|
||||||
current_trapframe: &TrapFrame,
|
current_trapframe: &TrapFrame,
|
||||||
) -> Result<(), SystemError> {
|
) -> 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中与架构相关的信息
|
/// PCB中与架构相关的信息
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ArchPCBInfo {
|
pub struct ArchPCBInfo {
|
||||||
@ -277,12 +326,16 @@ impl ArchPCBInfo {
|
|||||||
}
|
}
|
||||||
// ### 从另一个ArchPCBInfo处clone,但是保留部分字段不变
|
// ### 从另一个ArchPCBInfo处clone,但是保留部分字段不变
|
||||||
pub fn clone_from(&mut self, from: &Self) {
|
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)]
|
#[repr(C)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
struct FpDExtState {
|
struct FpDExtState {
|
||||||
f: [u64; 32],
|
f: [u64; 32],
|
||||||
fcsr: u32,
|
fcsr: u32,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user