121 lines
4.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use core::arch::asm;
use crate::{
arch::{asm::csr::CSR_SSTATUS, interrupt::TrapFrame},
process::{
fork::CloneFlags,
kthread::{kernel_thread_bootstrap_stage2, KernelThreadCreateInfo, KernelThreadMechanism},
Pid, ProcessManager,
},
};
use alloc::sync::Arc;
use asm_macros::restore_from_x6_to_x31;
use kdepends::memoffset::offset_of;
use riscv::register::sstatus::SPP;
use system_error::SystemError;
impl KernelThreadMechanism {
/// 伪造trapframe创建内核线程
///
/// ## 返回值
///
/// 返回创建的内核线程的pid
#[inline(never)]
pub fn __inner_create(
info: &Arc<KernelThreadCreateInfo>,
clone_flags: CloneFlags,
) -> Result<Pid, SystemError> {
// 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.a2 = 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);
}
}
/// 内核线程引导函数的第一阶段
///
/// 当内核线程开始执行时会先执行这个函数这个函数会将伪造的trapframe中的数据弹出然后跳转到第二阶段
///
/// 跳转之后指向Box<KernelThreadClosure>的指针将传入到stage2的函数
// #[naked]
// pub(super) unsafe extern "C" fn kernel_thread_bootstrap_stage1() {
// todo!()
// }
#[naked]
pub(super) unsafe extern "C" fn kernel_thread_bootstrap_stage1() {
// 这个函数要是naked的只是因为现在还没有实现而naked func不能打`unimplemented!()`
// 所以先写成了普通函数
asm!(concat!(
"
ld x3, {off_gp}(sp)
ld x5, {off_t0}(sp)
",
restore_from_x6_to_x31!(),
"
ld a0, {off_status}(sp)
csrw {csr_status}, a0
mv a0, a2
j {stage2_func}
"
),
csr_status = const CSR_SSTATUS,
off_status = const offset_of!(TrapFrame, status),
off_gp = const offset_of!(TrapFrame, gp),
off_t0 = const offset_of!(TrapFrame, t0),
off_t1 = const offset_of!(TrapFrame, t1),
off_t2 = const offset_of!(TrapFrame, t2),
off_s0 = const offset_of!(TrapFrame, s0),
off_s1 = const offset_of!(TrapFrame, s1),
off_a0 = const offset_of!(TrapFrame, a0),
off_a1 = const offset_of!(TrapFrame, a1),
off_a2 = const offset_of!(TrapFrame, a2),
off_a3 = const offset_of!(TrapFrame, a3),
off_a4 = const offset_of!(TrapFrame, a4),
off_a5 = const offset_of!(TrapFrame, a5),
off_a6 = const offset_of!(TrapFrame, a6),
off_a7 = const offset_of!(TrapFrame, a7),
off_s2 = const offset_of!(TrapFrame, s2),
off_s3 = const offset_of!(TrapFrame, s3),
off_s4 = const offset_of!(TrapFrame, s4),
off_s5 = const offset_of!(TrapFrame, s5),
off_s6 = const offset_of!(TrapFrame, s6),
off_s7 = const offset_of!(TrapFrame, s7),
off_s8 = const offset_of!(TrapFrame, s8),
off_s9 = const offset_of!(TrapFrame, s9),
off_s10 = const offset_of!(TrapFrame, s10),
off_s11 = const offset_of!(TrapFrame, s11),
off_t3 = const offset_of!(TrapFrame, t3),
off_t4 = const offset_of!(TrapFrame, t4),
off_t5 = const offset_of!(TrapFrame, t5),
off_t6 = const offset_of!(TrapFrame, t6),
stage2_func = sym jump_to_stage2,
options(noreturn),
);
}
fn jump_to_stage2(ptr: *const KernelThreadCreateInfo) {
unsafe { kernel_thread_bootstrap_stage2(ptr) };
}