xref: /DragonOS/kernel/src/init/initial_kthread.rs (revision f5b2038871d3441e1c7f32439ff422957e7ab828)
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     namespaces::NsProxy,
14     net::net_core::net_init,
15     process::{
16         exec::ProcInitInfo, kthread::KernelThreadMechanism, stdio::stdio_init, ProcessFlags,
17         ProcessManager,
18     },
19     smp::smp_init,
20     syscall::Syscall,
21 };
22 
23 use super::{cmdline::kenrel_cmdline_param_manager, initcall::do_initcalls};
24 
25 const INIT_PROC_TRYLIST: [&str; 3] = ["/bin/dragonreach", "/bin/init", "/bin/sh"];
26 
initial_kernel_thread() -> i3227 pub fn initial_kernel_thread() -> i32 {
28     kernel_init().unwrap_or_else(|err| {
29         log::error!("Failed to initialize kernel: {:?}", err);
30         panic!()
31     });
32 
33     switch_to_user();
34 }
35 
kernel_init() -> Result<(), SystemError>36 fn kernel_init() -> Result<(), SystemError> {
37     KernelThreadMechanism::init_stage2();
38     kenrel_init_freeable()?;
39     #[cfg(target_arch = "x86_64")]
40     crate::driver::disk::ahci::ahci_init()
41         .inspect_err(|e| log::error!("ahci_init failed: {:?}", e))
42         .ok();
43     virtio_probe();
44     mount_root_fs().expect("Failed to mount root fs");
45     e1000e_init();
46     net_init().unwrap_or_else(|err| {
47         error!("Failed to initialize network: {:?}", err);
48     });
49 
50     debug!("initial kernel thread done.");
51 
52     return Ok(());
53 }
54 
55 #[inline(never)]
kenrel_init_freeable() -> Result<(), SystemError>56 fn kenrel_init_freeable() -> Result<(), SystemError> {
57     do_initcalls().unwrap_or_else(|err| {
58         panic!("Failed to initialize subsystems: {:?}", err);
59     });
60     stdio_init().expect("Failed to initialize stdio");
61     smp_init();
62 
63     return Ok(());
64 }
65 
66 /// 切换到用户态
67 #[inline(never)]
switch_to_user() -> !68 fn switch_to_user() -> ! {
69     let current_pcb = ProcessManager::current_pcb();
70 
71     // 删除kthread的标志
72     current_pcb.flags().remove(ProcessFlags::KTHREAD);
73     current_pcb.worker_private().take();
74 
75     *current_pcb.sched_info().sched_policy.write_irqsave() = crate::sched::SchedPolicy::CFS;
76     drop(current_pcb);
77 
78     let mut proc_init_info = ProcInitInfo::new("");
79     proc_init_info.envs.push(CString::new("PATH=/").unwrap());
80     proc_init_info.args = kenrel_cmdline_param_manager().init_proc_args();
81     proc_init_info.envs = kenrel_cmdline_param_manager().init_proc_envs();
82 
83     let mut trap_frame = TrapFrame::new();
84 
85     if let Some(path) = kenrel_cmdline_param_manager().init_proc_path() {
86         log::info!("Boot with specified init process: {:?}", path);
87 
88         try_to_run_init_process(
89             path.as_c_str().to_str().unwrap(),
90             &mut proc_init_info,
91             &mut trap_frame,
92         )
93         .unwrap_or_else(|e| {
94             panic!(
95                 "Failed to run specified init process: {:?}, err: {:?}",
96                 path, e
97             )
98         });
99     } else {
100         let mut ok = false;
101         for path in INIT_PROC_TRYLIST.iter() {
102             if try_to_run_init_process(path, &mut proc_init_info, &mut trap_frame).is_ok() {
103                 ok = true;
104                 break;
105             }
106         }
107         if !ok {
108             panic!("Failed to run init process: No working init found.");
109         }
110     }
111     drop(proc_init_info);
112     // 需要确保执行到这里之后,上面所有的资源都已经释放(比如arc之类的)
113     compiler_fence(Ordering::SeqCst);
114 
115     unsafe { arch_switch_to_user(trap_frame) };
116 }
117 
try_to_run_init_process( path: &str, proc_init_info: &mut ProcInitInfo, trap_frame: &mut TrapFrame, ) -> Result<(), SystemError>118 fn try_to_run_init_process(
119     path: &str,
120     proc_init_info: &mut ProcInitInfo,
121     trap_frame: &mut TrapFrame,
122 ) -> Result<(), SystemError> {
123     proc_init_info.proc_name = CString::new(path).unwrap();
124     proc_init_info.args.insert(0, CString::new(path).unwrap());
125     if let Err(e) = run_init_process(proc_init_info, trap_frame) {
126         if e != SystemError::ENOENT {
127             error!(
128                 "Failed to run init process: {path} exists but couldn't execute it (error {:?})",
129                 e
130             );
131         }
132 
133         proc_init_info.args.remove(0);
134         return Err(e);
135     }
136     Ok(())
137 }
138 
run_init_process( proc_init_info: &ProcInitInfo, trap_frame: &mut TrapFrame, ) -> Result<(), SystemError>139 fn run_init_process(
140     proc_init_info: &ProcInitInfo,
141     trap_frame: &mut TrapFrame,
142 ) -> Result<(), SystemError> {
143     compiler_fence(Ordering::SeqCst);
144     ProcessManager::current_pcb().set_nsproxy(NsProxy::new()); // 初始化init进程的namespace
145     let path = proc_init_info.proc_name.to_str().unwrap();
146 
147     Syscall::do_execve(
148         path.to_string(),
149         proc_init_info.args.clone(),
150         proc_init_info.envs.clone(),
151         trap_frame,
152     )?;
153 
154     Ok(())
155 }
156