lib.rs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #![no_std]
  2. #![no_main]
  3. #![feature(c_size_t)]
  4. #![feature(concat_idents)]
  5. #![feature(arbitrary_self_types)]
  6. #![feature(get_mut_unchecked)]
  7. #![feature(macro_metavar_expr)]
  8. extern crate alloc;
  9. mod driver;
  10. mod fs;
  11. mod hash;
  12. mod io;
  13. mod kernel;
  14. mod kernel_init;
  15. mod net;
  16. mod path;
  17. mod prelude;
  18. mod rcu;
  19. mod sync;
  20. use crate::kernel::task::alloc_pid;
  21. use alloc::{ffi::CString, sync::Arc};
  22. use core::{
  23. hint::spin_loop,
  24. sync::atomic::{AtomicBool, Ordering},
  25. };
  26. use eonix_hal::{processor::CPU, traits::trap::IrqState, trap::disable_irqs_save};
  27. use eonix_mm::address::PRange;
  28. use eonix_runtime::{run::FutureRun, scheduler::Scheduler, task::Task};
  29. use kernel::{
  30. mem::GlobalPageAlloc,
  31. task::{
  32. new_thread_runnable, KernelStack, ProcessBuilder, ProcessList, ProgramLoader, ThreadBuilder,
  33. },
  34. vfs::{
  35. dentry::Dentry,
  36. mount::{do_mount, MS_NOATIME, MS_NODEV, MS_NOSUID, MS_RDONLY},
  37. FsContext,
  38. },
  39. CharDevice,
  40. };
  41. use kernel_init::setup_memory;
  42. use path::Path;
  43. use prelude::*;
  44. #[panic_handler]
  45. fn panic(info: &core::panic::PanicInfo) -> ! {
  46. if let Some(location) = info.location() {
  47. println_fatal!(
  48. "panicked at {}:{}:{}",
  49. location.file(),
  50. location.line(),
  51. location.column()
  52. );
  53. } else {
  54. println_fatal!("panicked at <UNKNOWN>");
  55. }
  56. println_fatal!();
  57. println_fatal!("{}", info.message());
  58. loop {}
  59. }
  60. static BSP_OK: AtomicBool = AtomicBool::new(false);
  61. #[eonix_hal::main]
  62. fn kernel_init(mut data: eonix_hal::bootstrap::BootStrapData) -> ! {
  63. setup_memory(&mut data);
  64. BSP_OK.store(true, Ordering::Release);
  65. #[cfg(target_arch = "riscv64")]
  66. {
  67. driver::sbi_console::init_console();
  68. }
  69. kernel::pcie::init_pcie().expect("Unable to initialize PCIe bus");
  70. // To satisfy the `Scheduler` "preempt count == 0" assertion.
  71. eonix_preempt::disable();
  72. // We need root dentry to be present in constructor of `FsContext`.
  73. // So call `init_vfs` first, then `init_multitasking`.
  74. Scheduler::init_local_scheduler::<KernelStack>();
  75. Scheduler::get().spawn::<KernelStack, _>(FutureRun::new(init_process(data.get_early_stack())));
  76. drop(data);
  77. unsafe {
  78. // SAFETY: `preempt::count()` == 1.
  79. Scheduler::goto_scheduler_noreturn()
  80. }
  81. }
  82. #[eonix_hal::ap_main]
  83. fn kernel_ap_main(_stack_range: PRange) -> ! {
  84. while BSP_OK.load(Ordering::Acquire) == false {
  85. // Wait for BSP to finish initializing.
  86. spin_loop();
  87. }
  88. Scheduler::init_local_scheduler::<KernelStack>();
  89. println_debug!("AP{} started", CPU::local().cpuid());
  90. eonix_preempt::disable();
  91. // TODO!!!!!: Free the stack after having switched to idle task.
  92. unsafe {
  93. // SAFETY: `preempt::count()` == 1.
  94. Scheduler::goto_scheduler_noreturn()
  95. }
  96. }
  97. async fn init_process(early_kstack: PRange) {
  98. unsafe {
  99. let irq_ctx = disable_irqs_save();
  100. // SAFETY: IRQ is disabled.
  101. GlobalPageAlloc::add_pages(early_kstack);
  102. irq_ctx.restore();
  103. }
  104. CharDevice::init().unwrap();
  105. #[cfg(target_arch = "x86_64")]
  106. {
  107. // We might want the serial initialized as soon as possible.
  108. driver::serial::init().unwrap();
  109. driver::e1000e::register_e1000e_driver();
  110. driver::ahci::register_ahci_driver();
  111. }
  112. #[cfg(target_arch = "riscv64")]
  113. {
  114. driver::virtio::init_virtio_devices();
  115. driver::e1000e::register_e1000e_driver();
  116. driver::ahci::register_ahci_driver();
  117. }
  118. fs::tmpfs::init();
  119. fs::procfs::init();
  120. fs::fat32::init();
  121. let load_info = {
  122. // mount fat32 /mnt directory
  123. let fs_context = FsContext::global();
  124. let mnt_dir = Dentry::open(fs_context, Path::new(b"/mnt/").unwrap(), true).unwrap();
  125. mnt_dir.mkdir(0o755).unwrap();
  126. do_mount(
  127. &mnt_dir,
  128. "/dev/sda",
  129. "/mnt",
  130. "fat32",
  131. MS_RDONLY | MS_NOATIME | MS_NODEV | MS_NOSUID,
  132. )
  133. .unwrap();
  134. let init_names = [
  135. &b"/sbin/init"[..],
  136. &b"/init"[..],
  137. &b"/bin/busybox"[..],
  138. &b"/mnt/busybox"[..],
  139. ];
  140. let mut init_name = None;
  141. let mut init = None;
  142. for name in &init_names {
  143. if let Ok(dentry) = Dentry::open(fs_context, Path::new(name).unwrap(), true) {
  144. if dentry.is_valid() {
  145. init_name = Some(*name);
  146. init = Some(dentry);
  147. break;
  148. }
  149. }
  150. }
  151. let init = init.expect("No init binary found in the system.");
  152. let init_name = init_name.unwrap();
  153. let argv = vec![
  154. CString::new(init_name).unwrap(),
  155. CString::new("sh").unwrap(),
  156. CString::new("/mnt/initsh").unwrap(),
  157. ];
  158. let envp = vec![
  159. CString::new("LANG=C").unwrap(),
  160. CString::new("HOME=/root").unwrap(),
  161. CString::new("PATH=/mnt").unwrap(),
  162. CString::new("PWD=/").unwrap(),
  163. ];
  164. ProgramLoader::parse(init.clone())
  165. .unwrap()
  166. .load(argv, envp)
  167. .unwrap()
  168. };
  169. let thread_builder = ThreadBuilder::new()
  170. .name(Arc::from(&b"busybox"[..]))
  171. .entry(load_info.entry_ip, load_info.sp);
  172. let mut process_list = Task::block_on(ProcessList::get().write());
  173. let (thread, process) = ProcessBuilder::new()
  174. .pid(alloc_pid())
  175. .mm_list(load_info.mm_list)
  176. .thread_builder(thread_builder)
  177. .build(&mut process_list);
  178. process_list.set_init_process(process);
  179. // TODO!!!: Remove this.
  180. thread.files.open_console();
  181. Scheduler::get().spawn::<KernelStack, _>(new_thread_runnable(thread));
  182. }