initial_kthread.rs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. //! 这个文件内放置初始内核线程的代码。
  2. use core::sync::atomic::{compiler_fence, Ordering};
  3. use alloc::{ffi::CString, string::ToString};
  4. use log::{debug, error};
  5. use system_error::SystemError;
  6. use crate::{
  7. arch::{interrupt::TrapFrame, process::arch_switch_to_user},
  8. driver::net::e1000e::e1000e::e1000e_init,
  9. filesystem::vfs::vcore::mount_root_fs,
  10. namespaces::NsProxy,
  11. net::net_core::net_init,
  12. process::{
  13. exec::ProcInitInfo, execve::do_execve, kthread::KernelThreadMechanism, stdio::stdio_init,
  14. ProcessFlags, ProcessManager,
  15. },
  16. smp::smp_init,
  17. };
  18. use super::{cmdline::kenrel_cmdline_param_manager, initcall::do_initcalls};
  19. const INIT_PROC_TRYLIST: [(&str, Option<&str>); 4] = [
  20. ("/bin/dragonreach", None),
  21. ("/bin/busybox", Some("init")),
  22. ("/bin/init", None),
  23. ("/bin/sh", None),
  24. ];
  25. pub fn initial_kernel_thread() -> i32 {
  26. kernel_init().unwrap_or_else(|err| {
  27. log::error!("Failed to initialize kernel: {:?}", err);
  28. panic!()
  29. });
  30. switch_to_user();
  31. }
  32. fn kernel_init() -> Result<(), SystemError> {
  33. KernelThreadMechanism::init_stage2();
  34. kenrel_init_freeable()?;
  35. #[cfg(target_arch = "x86_64")]
  36. crate::driver::disk::ahci::ahci_init()
  37. .inspect_err(|e| log::error!("ahci_init failed: {:?}", e))
  38. .ok();
  39. mount_root_fs().expect("Failed to mount root fs");
  40. e1000e_init();
  41. net_init().unwrap_or_else(|err| {
  42. error!("Failed to initialize network: {:?}", err);
  43. });
  44. debug!("initial kernel thread done.");
  45. return Ok(());
  46. }
  47. #[inline(never)]
  48. fn kenrel_init_freeable() -> Result<(), SystemError> {
  49. do_initcalls().unwrap_or_else(|err| {
  50. panic!("Failed to initialize subsystems: {:?}", err);
  51. });
  52. stdio_init().expect("Failed to initialize stdio");
  53. smp_init();
  54. return Ok(());
  55. }
  56. /// 切换到用户态
  57. #[inline(never)]
  58. fn switch_to_user() -> ! {
  59. let current_pcb = ProcessManager::current_pcb();
  60. // 删除kthread的标志
  61. current_pcb.flags().remove(ProcessFlags::KTHREAD);
  62. current_pcb.worker_private().take();
  63. *current_pcb.sched_info().sched_policy.write_irqsave() = crate::sched::SchedPolicy::CFS;
  64. drop(current_pcb);
  65. let mut proc_init_info = ProcInitInfo::new("");
  66. proc_init_info.envs.push(CString::new("PATH=/").unwrap());
  67. proc_init_info.args = kenrel_cmdline_param_manager().init_proc_args();
  68. proc_init_info.envs = kenrel_cmdline_param_manager().init_proc_envs();
  69. let mut trap_frame = TrapFrame::new();
  70. if let Some(path) = kenrel_cmdline_param_manager().init_proc_path() {
  71. log::info!("Boot with specified init process: {:?}", path);
  72. try_to_run_init_process(
  73. path.as_c_str().to_str().unwrap(),
  74. &mut proc_init_info,
  75. &None,
  76. &mut trap_frame,
  77. )
  78. .unwrap_or_else(|e| {
  79. panic!(
  80. "Failed to run specified init process: {:?}, err: {:?}",
  81. path, e
  82. )
  83. });
  84. } else {
  85. let mut ok = false;
  86. for (path, ext_args) in INIT_PROC_TRYLIST.iter() {
  87. if try_to_run_init_process(path, &mut proc_init_info, ext_args, &mut trap_frame).is_ok()
  88. {
  89. ok = true;
  90. break;
  91. }
  92. }
  93. if !ok {
  94. panic!("Failed to run init process: No working init found.");
  95. }
  96. }
  97. drop(proc_init_info);
  98. // 需要确保执行到这里之后,上面所有的资源都已经释放(比如arc之类的)
  99. compiler_fence(Ordering::SeqCst);
  100. unsafe { arch_switch_to_user(trap_frame) };
  101. }
  102. fn try_to_run_init_process(
  103. path: &str,
  104. proc_init_info: &mut ProcInitInfo,
  105. ext_args: &Option<&str>,
  106. trap_frame: &mut TrapFrame,
  107. ) -> Result<(), SystemError> {
  108. log::debug!("Trying to run init process at {:?}", path);
  109. let mut args_to_insert = alloc::vec::Vec::new();
  110. args_to_insert.push(CString::new(path).unwrap());
  111. if let Some(ext_args) = ext_args {
  112. // Split ext_args by whitespace and trim each part
  113. for arg in ext_args.split_whitespace() {
  114. args_to_insert.push(CString::new(arg.trim()).unwrap());
  115. }
  116. }
  117. proc_init_info.proc_name = CString::new(path).unwrap();
  118. let elements_to_remove = args_to_insert.len();
  119. let old_args = core::mem::replace(&mut proc_init_info.args, args_to_insert);
  120. proc_init_info.args.extend(old_args);
  121. if let Err(e) = run_init_process(proc_init_info, trap_frame) {
  122. if e != SystemError::ENOENT {
  123. error!(
  124. "Failed to run init process: {path} exists but couldn't execute it (error {:?})",
  125. e
  126. );
  127. }
  128. proc_init_info.args.drain(0..elements_to_remove);
  129. return Err(e);
  130. }
  131. Ok(())
  132. }
  133. fn run_init_process(
  134. proc_init_info: &ProcInitInfo,
  135. trap_frame: &mut TrapFrame,
  136. ) -> Result<(), SystemError> {
  137. compiler_fence(Ordering::SeqCst);
  138. ProcessManager::current_pcb().set_nsproxy(NsProxy::new()); // 初始化init进程的namespace
  139. let path = proc_init_info.proc_name.to_str().unwrap();
  140. do_execve(
  141. path.to_string(),
  142. proc_init_info.args.clone(),
  143. proc_init_info.envs.clone(),
  144. trap_frame,
  145. )?;
  146. Ok(())
  147. }