xref: /DragonOS/kernel/src/init/initial_kthread.rs (revision 9fa0e95eeed8630a8a69c874090af2f10e8eee02)
1c566df45SLoGin //! 这个文件内放置初始内核线程的代码。
2c566df45SLoGin 
3f75cb0f8SLoGin use core::sync::atomic::{compiler_fence, Ordering};
4f75cb0f8SLoGin 
5703ce5a7SLoGin 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 
initial_kernel_thread() -> i3221c566df45SLoGin 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 
kernel_init() -> Result<(), SystemError>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 
36232570aeSLoGin     #[cfg(target_arch = "x86_64")]
37232570aeSLoGin     crate::driver::disk::ahci::ahci_init()
38*9fa0e95eSLoGin         .inspect_err(|e| log::error!("ahci_init failed: {:?}", e))
39232570aeSLoGin         .ok();
40*9fa0e95eSLoGin     virtio_probe();
41731bc2b3SLoGin     mount_root_fs().expect("Failed to mount root fs");
42c566df45SLoGin     e1000e_init();
43c566df45SLoGin     net_init().unwrap_or_else(|err| {
442eab6dd7S曾俊         error!("Failed to initialize network: {:?}", err);
45c566df45SLoGin     });
46c566df45SLoGin 
472eab6dd7S曾俊     debug!("initial kernel thread done.");
48c566df45SLoGin 
49c566df45SLoGin     return Ok(());
50c566df45SLoGin }
51c566df45SLoGin 
52c566df45SLoGin #[inline(never)]
kenrel_init_freeable() -> Result<(), SystemError>53c566df45SLoGin fn kenrel_init_freeable() -> Result<(), SystemError> {
54c566df45SLoGin     do_initcalls().unwrap_or_else(|err| {
55c566df45SLoGin         panic!("Failed to initialize subsystems: {:?}", err);
56c566df45SLoGin     });
573959e94dS曾俊     stdio_init().expect("Failed to initialize stdio");
588cb2e9b3SLoGin     smp_init();
598cb2e9b3SLoGin 
60c566df45SLoGin     return Ok(());
61c566df45SLoGin }
62c566df45SLoGin 
63c566df45SLoGin /// 切换到用户态
64f75cb0f8SLoGin #[inline(never)]
switch_to_user() -> !65f75cb0f8SLoGin fn switch_to_user() -> ! {
66f75cb0f8SLoGin     let current_pcb = ProcessManager::current_pcb();
67f75cb0f8SLoGin 
68f75cb0f8SLoGin     // 删除kthread的标志
69f75cb0f8SLoGin     current_pcb.flags().remove(ProcessFlags::KTHREAD);
70f75cb0f8SLoGin     current_pcb.worker_private().take();
71f75cb0f8SLoGin 
72f75cb0f8SLoGin     *current_pcb.sched_info().sched_policy.write_irqsave() = crate::sched::SchedPolicy::CFS;
73f75cb0f8SLoGin     drop(current_pcb);
74f75cb0f8SLoGin 
75f75cb0f8SLoGin     let mut trap_frame = TrapFrame::new();
76f75cb0f8SLoGin     // 逐个尝试运行init进程
77f75cb0f8SLoGin     if try_to_run_init_process("/bin/dragonreach", &mut trap_frame).is_err()
78f75cb0f8SLoGin         && try_to_run_init_process("/bin/init", &mut trap_frame).is_err()
79f75cb0f8SLoGin         && try_to_run_init_process("/bin/sh", &mut trap_frame).is_err()
80f75cb0f8SLoGin     {
81f75cb0f8SLoGin         panic!("Failed to run init process: No working init found.");
82f75cb0f8SLoGin     }
83f75cb0f8SLoGin 
84f75cb0f8SLoGin     // 需要确保执行到这里之后,上面所有的资源都已经释放(比如arc之类的)
85942cf26bSLoGin     compiler_fence(Ordering::SeqCst);
86f75cb0f8SLoGin 
87f75cb0f8SLoGin     unsafe { arch_switch_to_user(trap_frame) };
88f75cb0f8SLoGin }
89f75cb0f8SLoGin 
try_to_run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError>90f75cb0f8SLoGin fn try_to_run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
91703ce5a7SLoGin     if let Err(e) = run_init_process(path, trap_frame) {
92f75cb0f8SLoGin         if e != SystemError::ENOENT {
932eab6dd7S曾俊             error!(
94f75cb0f8SLoGin                 "Failed to run init process: {path} exists but couldn't execute it (error {:?})",
95f75cb0f8SLoGin                 e
96f75cb0f8SLoGin             );
97f75cb0f8SLoGin         }
98f75cb0f8SLoGin         return Err(e);
99f75cb0f8SLoGin     }
100f75cb0f8SLoGin     Ok(())
101f75cb0f8SLoGin }
102f75cb0f8SLoGin 
run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError>103703ce5a7SLoGin fn run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
104703ce5a7SLoGin     let argv = vec![CString::new(path).unwrap()];
105703ce5a7SLoGin     let envp = vec![CString::new("PATH=/").unwrap()];
106c566df45SLoGin 
107f75cb0f8SLoGin     compiler_fence(Ordering::SeqCst);
108703ce5a7SLoGin     Syscall::do_execve(path.to_string(), argv, envp, trap_frame)?;
109f75cb0f8SLoGin     Ok(())
110c566df45SLoGin }
111