xref: /DragonOS/kernel/src/init/initial_kthread.rs (revision 59a6bcf6aee15a11a16431bdf875905c5ecf9157)
1 //! 这个文件内放置初始内核线程的代码。
2 
3 use core::sync::atomic::{compiler_fence, Ordering};
4 
5 use alloc::{ffi::CString, string::ToString};
6 use log::{debug, error};
7 use system_error::SystemError;
8 
9 use crate::{
10     arch::{interrupt::TrapFrame, process::arch_switch_to_user},
11     driver::{net::e1000e::e1000e::e1000e_init, virtio::virtio::virtio_probe},
12     filesystem::vfs::core::mount_root_fs,
13     net::net_core::net_init,
14     process::{kthread::KernelThreadMechanism, stdio::stdio_init, ProcessFlags, ProcessManager},
15     smp::smp_init,
16     syscall::Syscall,
17 };
18 
19 use super::initcall::do_initcalls;
20 
21 pub fn initial_kernel_thread() -> i32 {
22     kernel_init().unwrap_or_else(|err| {
23         log::error!("Failed to initialize kernel: {:?}", err);
24         panic!()
25     });
26 
27     switch_to_user();
28 }
29 
30 fn kernel_init() -> Result<(), SystemError> {
31     KernelThreadMechanism::init_stage2();
32     kenrel_init_freeable()?;
33     #[cfg(target_arch = "x86_64")]
34     crate::driver::disk::ahci::ahci_init()
35         .inspect_err(|e| log::error!("ahci_init failed: {:?}", e))
36         .ok();
37     virtio_probe();
38     mount_root_fs().expect("Failed to mount root fs");
39     e1000e_init();
40     net_init().unwrap_or_else(|err| {
41         error!("Failed to initialize network: {:?}", err);
42     });
43 
44     debug!("initial kernel thread done.");
45 
46     return Ok(());
47 }
48 
49 #[inline(never)]
50 fn kenrel_init_freeable() -> Result<(), SystemError> {
51     do_initcalls().unwrap_or_else(|err| {
52         panic!("Failed to initialize subsystems: {:?}", err);
53     });
54     stdio_init().expect("Failed to initialize stdio");
55     smp_init();
56 
57     return Ok(());
58 }
59 
60 /// 切换到用户态
61 #[inline(never)]
62 fn switch_to_user() -> ! {
63     let current_pcb = ProcessManager::current_pcb();
64 
65     // 删除kthread的标志
66     current_pcb.flags().remove(ProcessFlags::KTHREAD);
67     current_pcb.worker_private().take();
68 
69     *current_pcb.sched_info().sched_policy.write_irqsave() = crate::sched::SchedPolicy::CFS;
70     drop(current_pcb);
71 
72     let mut trap_frame = TrapFrame::new();
73     // 逐个尝试运行init进程
74     if try_to_run_init_process("/bin/dragonreach", &mut trap_frame).is_err()
75         && try_to_run_init_process("/bin/init", &mut trap_frame).is_err()
76         && try_to_run_init_process("/bin/sh", &mut trap_frame).is_err()
77     {
78         panic!("Failed to run init process: No working init found.");
79     }
80 
81     // 需要确保执行到这里之后,上面所有的资源都已经释放(比如arc之类的)
82     compiler_fence(Ordering::SeqCst);
83 
84     unsafe { arch_switch_to_user(trap_frame) };
85 }
86 
87 fn try_to_run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
88     if let Err(e) = run_init_process(path, trap_frame) {
89         if e != SystemError::ENOENT {
90             error!(
91                 "Failed to run init process: {path} exists but couldn't execute it (error {:?})",
92                 e
93             );
94         }
95         return Err(e);
96     }
97     Ok(())
98 }
99 
100 fn run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
101     let argv = vec![CString::new(path).unwrap()];
102     let envp = vec![CString::new("PATH=/").unwrap()];
103 
104     compiler_fence(Ordering::SeqCst);
105     Syscall::do_execve(path.to_string(), argv, envp, trap_frame)?;
106     Ok(())
107 }
108