xref: /DragonOS/kernel/src/arch/x86_64/process/kthread.rs (revision bd70d2d1f490aabd570a5301b858bd5eb04149fa)
1 use core::arch::asm;
2 
3 use alloc::sync::Arc;
4 use system_error::SystemError;
5 
6 use crate::{
7     arch::{
8         interrupt::TrapFrame,
9         process::table::{KERNEL_CS, KERNEL_DS},
10     },
11     process::{
12         fork::CloneFlags,
13         kthread::{kernel_thread_bootstrap_stage2, KernelThreadCreateInfo, KernelThreadMechanism},
14         Pid, ProcessManager,
15     },
16 };
17 
18 impl KernelThreadMechanism {
19     /// 伪造trapframe,创建内核线程
20     ///
21     /// ## 返回值
22     ///
23     /// 返回创建的内核线程的pid
__inner_create( info: &Arc<KernelThreadCreateInfo>, clone_flags: CloneFlags, ) -> Result<Pid, SystemError>24     pub fn __inner_create(
25         info: &Arc<KernelThreadCreateInfo>,
26         clone_flags: CloneFlags,
27     ) -> Result<Pid, SystemError> {
28         // WARNING: If create failed, we must drop the info manually or it will cause memory leak. (refcount will not decrease when create failed)
29         let create_info: *const KernelThreadCreateInfo =
30             KernelThreadCreateInfo::generate_unsafe_arc_ptr(info.clone());
31 
32         let mut frame = TrapFrame::new();
33         frame.rbx = create_info as usize as u64;
34         frame.ds = KERNEL_DS.bits() as u64;
35         frame.es = KERNEL_DS.bits() as u64;
36         frame.cs = KERNEL_CS.bits() as u64;
37         frame.ss = KERNEL_DS.bits() as u64;
38 
39         // 使能中断
40         frame.rflags |= 1 << 9;
41 
42         frame.rip = kernel_thread_bootstrap_stage1 as usize as u64;
43 
44         // fork失败的话,子线程不会执行。否则将导致内存安全问题。
45         let pid = ProcessManager::fork(&frame, clone_flags).inspect_err(|_e| {
46             unsafe { KernelThreadCreateInfo::parse_unsafe_arc_ptr(create_info) };
47         })?;
48 
49         ProcessManager::find(pid)
50             .unwrap()
51             .set_name(info.name().clone());
52 
53         return Ok(pid);
54     }
55 }
56 
57 /// 内核线程引导函数的第一阶段
58 ///
59 /// 当内核线程开始执行时,会先执行这个函数,这个函数会将伪造的trapframe中的数据弹出,然后跳转到第二阶段
60 ///
61 /// 跳转之后,指向Box<KernelThreadClosure>的指针将传入到stage2的函数
62 #[naked]
kernel_thread_bootstrap_stage1()63 pub(super) unsafe extern "sysv64" fn kernel_thread_bootstrap_stage1() {
64     asm!(
65         concat!(
66             "
67 
68             pop r15
69             pop r14
70             pop r13
71             pop r12
72             pop r11
73             pop r10
74             pop r9
75             pop r8
76             pop rbx
77             pop rcx
78             pop rdx
79             pop rsi
80             pop rdi
81             pop rbp
82             pop rax
83             mov ds, ax
84             pop rax
85             mov es, ax
86             pop rax
87             add rsp, 0x20
88             popfq
89             add rsp, 0x10
90             mov rdi, rbx
91             jmp {stage2_func}
92             "
93         ),
94         stage2_func = sym kernel_thread_bootstrap_stage2,
95         options(noreturn)
96     )
97 }
98