lib.rs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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::serial::init().unwrap();
  115. driver::virtio::init_virtio_devices();
  116. driver::e1000e::register_e1000e_driver();
  117. driver::ahci::register_ahci_driver();
  118. driver::goldfish_rtc::probe();
  119. }
  120. fs::tmpfs::init();
  121. fs::procfs::init();
  122. fs::fat32::init();
  123. fs::ext4::init();
  124. let load_info = {
  125. // mount fat32 /mnt directory
  126. let fs_context = FsContext::global();
  127. let mnt_dir = Dentry::open(fs_context, Path::new(b"/mnt/").unwrap(), true).unwrap();
  128. mnt_dir.mkdir(0o755).unwrap();
  129. do_mount(
  130. &mnt_dir,
  131. "/dev/sda",
  132. "/mnt",
  133. "fat32",
  134. MS_RDONLY | MS_NOATIME | MS_NODEV | MS_NOSUID,
  135. )
  136. .unwrap();
  137. let init_names = [
  138. &b"/sbin/init"[..],
  139. &b"/init"[..],
  140. &b"/bin/busybox"[..],
  141. &b"/mnt/busybox"[..],
  142. ];
  143. let mut init_name = None;
  144. let mut init = None;
  145. for name in &init_names {
  146. if let Ok(dentry) = Dentry::open(fs_context, Path::new(name).unwrap(), true) {
  147. if dentry.is_valid() {
  148. init_name = Some(*name);
  149. init = Some(dentry);
  150. break;
  151. }
  152. }
  153. }
  154. let init = init.expect("No init binary found in the system.");
  155. let init_name = init_name.unwrap();
  156. let argv = vec![
  157. CString::new(init_name).unwrap(),
  158. CString::new("sh").unwrap(),
  159. CString::new("/mnt/initsh").unwrap(),
  160. ];
  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(init.clone())
  168. .unwrap()
  169. .load(argv, envp)
  170. .unwrap()
  171. };
  172. let thread_builder = ThreadBuilder::new()
  173. .name(Arc::from(&b"busybox"[..]))
  174. .entry(load_info.entry_ip, load_info.sp);
  175. let mut process_list = Task::block_on(ProcessList::get().write());
  176. let (thread, process) = ProcessBuilder::new()
  177. .pid(alloc_pid())
  178. .mm_list(load_info.mm_list)
  179. .thread_builder(thread_builder)
  180. .build(&mut process_list);
  181. process_list.set_init_process(process);
  182. // TODO!!!: Remove this.
  183. thread.files.open_console();
  184. Scheduler::get().spawn::<KernelStack, _>(new_thread_runnable(thread));
  185. }