lib.rs 5.1 KB

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