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