xref: /DragonOS/kernel/src/init/initial_kthread.rs (revision 4afc5b7b7bed743d18c058e4843dcbdb2f3ad751)
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         panic!("Failed to initialize kernel: {:?}", err);
24     });
25 
26     switch_to_user();
27 }
28 
29 fn kernel_init() -> Result<(), SystemError> {
30     KernelThreadMechanism::init_stage2();
31     kenrel_init_freeable()?;
32 
33     // 由于目前加锁,速度过慢,所以先不开启双缓冲
34     // scm_enable_double_buffer().expect("Failed to enable double buffer");
35 
36     #[cfg(target_arch = "x86_64")]
37     crate::driver::disk::ahci::ahci_init().expect("Failed to initialize AHCI");
38     virtio_probe();
39     mount_root_fs().expect("Failed to mount root fs");
40     e1000e_init();
41     net_init().unwrap_or_else(|err| {
42         error!("Failed to initialize network: {:?}", err);
43     });
44 
45     debug!("initial kernel thread done.");
46 
47     return Ok(());
48 }
49 
50 #[inline(never)]
51 fn kenrel_init_freeable() -> Result<(), SystemError> {
52     do_initcalls().unwrap_or_else(|err| {
53         panic!("Failed to initialize subsystems: {:?}", err);
54     });
55     stdio_init().expect("Failed to initialize stdio");
56     smp_init();
57 
58     return Ok(());
59 }
60 
61 /// 切换到用户态
62 #[inline(never)]
63 fn switch_to_user() -> ! {
64     let current_pcb = ProcessManager::current_pcb();
65 
66     // 删除kthread的标志
67     current_pcb.flags().remove(ProcessFlags::KTHREAD);
68     current_pcb.worker_private().take();
69 
70     *current_pcb.sched_info().sched_policy.write_irqsave() = crate::sched::SchedPolicy::CFS;
71     drop(current_pcb);
72 
73     let mut trap_frame = TrapFrame::new();
74     // 逐个尝试运行init进程
75     if try_to_run_init_process("/bin/dragonreach", &mut trap_frame).is_err()
76         && try_to_run_init_process("/bin/init", &mut trap_frame).is_err()
77         && try_to_run_init_process("/bin/sh", &mut trap_frame).is_err()
78     {
79         panic!("Failed to run init process: No working init found.");
80     }
81 
82     // 需要确保执行到这里之后,上面所有的资源都已经释放(比如arc之类的)
83     compiler_fence(Ordering::SeqCst);
84 
85     unsafe { arch_switch_to_user(trap_frame) };
86 }
87 
88 fn try_to_run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
89     if let Err(e) = run_init_process(path, trap_frame) {
90         if e != SystemError::ENOENT {
91             error!(
92                 "Failed to run init process: {path} exists but couldn't execute it (error {:?})",
93                 e
94             );
95         }
96         return Err(e);
97     }
98     Ok(())
99 }
100 
101 fn run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
102     let argv = vec![CString::new(path).unwrap()];
103     let envp = vec![CString::new("PATH=/").unwrap()];
104 
105     compiler_fence(Ordering::SeqCst);
106     Syscall::do_execve(path.to_string(), argv, envp, trap_frame)?;
107     Ok(())
108 }
109