lib.rs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #![no_std]
  2. #![no_main]
  3. #![feature(allocator_api)]
  4. #![feature(c_size_t)]
  5. #![feature(coerce_unsized)]
  6. #![feature(arbitrary_self_types)]
  7. #![feature(get_mut_unchecked)]
  8. #![feature(macro_metavar_expr)]
  9. #![feature(unsize)]
  10. extern crate alloc;
  11. #[macro_use]
  12. extern crate static_assertions;
  13. mod driver;
  14. mod fs;
  15. mod hash;
  16. mod io;
  17. mod kernel;
  18. mod kernel_init;
  19. mod net;
  20. mod panic;
  21. mod path;
  22. mod prelude;
  23. mod rcu;
  24. mod sync;
  25. use alloc::ffi::CString;
  26. use core::hint::spin_loop;
  27. use core::sync::atomic::{AtomicBool, Ordering};
  28. use eonix_hal::processor::CPU;
  29. use eonix_hal::symbol_addr;
  30. use eonix_hal::traits::trap::{IrqState, RawTrapContext, TrapReturn};
  31. use eonix_hal::trap::{disable_irqs_save, TrapContext};
  32. use eonix_mm::address::PRange;
  33. use eonix_runtime::scheduler::RUNTIME;
  34. use kernel::mem::GlobalPageAlloc;
  35. use kernel::task::{KernelStack, ProcessList, ProgramLoader};
  36. use kernel::vfs::dentry::Dentry;
  37. use kernel::vfs::mount::{
  38. do_mount, MS_NOATIME, MS_NODEV, MS_NOSUID, MS_RDONLY,
  39. };
  40. use kernel::vfs::types::Permission;
  41. use kernel::vfs::FsContext;
  42. use kernel::{shutdown_system, CharDevice};
  43. use kernel_init::setup_memory;
  44. use path::Path;
  45. use prelude::*;
  46. static BSP_OK: AtomicBool = AtomicBool::new(false);
  47. #[eonix_hal::main]
  48. fn kernel_init(mut data: eonix_hal::bootstrap::BootStrapData) -> ! {
  49. setup_memory(&mut data);
  50. #[cfg(target_arch = "riscv64")]
  51. {
  52. driver::sbi_console::init_console();
  53. }
  54. BSP_OK.store(true, Ordering::Release);
  55. RUNTIME.spawn(init_process(data.get_early_stack()));
  56. drop(data);
  57. let mut ctx = TrapContext::new();
  58. let stack = KernelStack::new();
  59. ctx.set_interrupt_enabled(true);
  60. ctx.set_user_mode(false);
  61. ctx.set_kernel_call_frame(symbol_addr!(standard_main), &stack, None, &[]);
  62. core::mem::forget(stack);
  63. unsafe {
  64. ctx.trap_return_noreturn();
  65. }
  66. }
  67. #[eonix_hal::ap_main]
  68. fn kernel_ap_main(_stack_range: PRange) -> ! {
  69. while BSP_OK.load(Ordering::Acquire) == false {
  70. // Wait for BSP to finish initializing.
  71. spin_loop();
  72. }
  73. println_debug!("AP{} started", CPU::local().cpuid());
  74. let mut ctx = TrapContext::new();
  75. let stack = KernelStack::new();
  76. ctx.set_interrupt_enabled(true);
  77. ctx.set_user_mode(false);
  78. ctx.set_kernel_call_frame(symbol_addr!(standard_main), &stack, None, &[]);
  79. core::mem::forget(stack);
  80. unsafe {
  81. ctx.trap_return_noreturn();
  82. }
  83. }
  84. fn standard_main() -> ! {
  85. RUNTIME.enter();
  86. shutdown_system();
  87. }
  88. async fn init_process(early_kstack: PRange) {
  89. unsafe {
  90. let irq_ctx = disable_irqs_save();
  91. // SAFETY: IRQ is disabled.
  92. GlobalPageAlloc::add_pages(early_kstack);
  93. irq_ctx.restore();
  94. }
  95. kernel::pcie::init_pcie().expect("Unable to initialize PCIe bus");
  96. CharDevice::init().unwrap();
  97. #[cfg(target_arch = "x86_64")]
  98. {
  99. // We might want the serial initialized as soon as possible.
  100. driver::serial::init().unwrap();
  101. driver::e1000e::register_e1000e_driver().await;
  102. driver::ahci::register_ahci_driver().await;
  103. }
  104. #[cfg(target_arch = "riscv64")]
  105. {
  106. driver::serial::init().unwrap();
  107. driver::virtio::init_virtio_devices();
  108. driver::e1000e::register_e1000e_driver().await;
  109. driver::ahci::register_ahci_driver().await;
  110. driver::goldfish_rtc::probe();
  111. }
  112. #[cfg(target_arch = "loongarch64")]
  113. {
  114. driver::serial::init().unwrap();
  115. driver::virtio::init_virtio_devices();
  116. driver::e1000e::register_e1000e_driver().await;
  117. driver::ahci::register_ahci_driver().await;
  118. }
  119. fs::tmpfs::init();
  120. fs::procfs::init().await;
  121. fs::fat32::init();
  122. // fs::ext4::init();
  123. let load_info = {
  124. // mount fat32 /mnt directory
  125. let fs_context = FsContext::global();
  126. let mnt_dir =
  127. Dentry::open(fs_context, Path::new(b"/mnt/").unwrap(), true)
  128. .await
  129. .unwrap();
  130. mnt_dir
  131. .mkdir(Permission::new(0o755))
  132. .await
  133. .expect("Failed to create /mnt directory");
  134. do_mount(
  135. &mnt_dir,
  136. "/dev/sda",
  137. "/mnt",
  138. "fat32",
  139. MS_RDONLY | MS_NOATIME | MS_NODEV | MS_NOSUID,
  140. )
  141. .await
  142. .unwrap();
  143. let init_names =
  144. [&b"/init"[..], &b"/sbin/init"[..], &b"/mnt/initsh"[..]];
  145. let mut init_name = None;
  146. let mut init = None;
  147. for name in init_names {
  148. if let Ok(dentry) =
  149. Dentry::open(fs_context, Path::new(name).unwrap(), true).await
  150. {
  151. if dentry.is_valid() {
  152. init_name = Some(CString::new(name).unwrap());
  153. init = Some(dentry);
  154. break;
  155. }
  156. }
  157. }
  158. let init = init.expect("No init binary found in the system.");
  159. let init_name = init_name.unwrap();
  160. let argv = vec![init_name.clone()];
  161. let envp = vec![
  162. CString::new("LANG=C").unwrap(),
  163. CString::new("HOME=/root").unwrap(),
  164. CString::new("PATH=/mnt").unwrap(),
  165. CString::new("PWD=/").unwrap(),
  166. ];
  167. ProgramLoader::parse(fs_context, init_name, init.clone(), argv, envp)
  168. .await
  169. .expect("Failed to parse init program")
  170. .load()
  171. .await
  172. .expect("Failed to load init program")
  173. };
  174. ProcessList::sys_init(load_info).await;
  175. }