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() 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)] 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, 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 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