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