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
initial_kernel_thread() -> i3221 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
kernel_init() -> Result<(), SystemError>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()
38 .inspect_err(|e| log::error!("ahci_init failed: {:?}", e))
39 .ok();
40 virtio_probe();
41 mount_root_fs().expect("Failed to mount root fs");
42 e1000e_init();
43 net_init().unwrap_or_else(|err| {
44 error!("Failed to initialize network: {:?}", err);
45 });
46
47 debug!("initial kernel thread done.");
48
49 return Ok(());
50 }
51
52 #[inline(never)]
kenrel_init_freeable() -> Result<(), SystemError>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)]
switch_to_user() -> !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
try_to_run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError>90 fn try_to_run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
91 if let Err(e) = run_init_process(path, trap_frame) {
92 if e != SystemError::ENOENT {
93 error!(
94 "Failed to run init process: {path} exists but couldn't execute it (error {:?})",
95 e
96 );
97 }
98 return Err(e);
99 }
100 Ok(())
101 }
102
run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError>103 fn run_init_process(path: &str, trap_frame: &mut TrapFrame) -> Result<(), SystemError> {
104 let argv = vec![CString::new(path).unwrap()];
105 let envp = vec![CString::new("PATH=/").unwrap()];
106
107 compiler_fence(Ordering::SeqCst);
108 Syscall::do_execve(path.to_string(), argv, envp, trap_frame)?;
109 Ok(())
110 }
111