boot.rs 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. use core::hint::spin_loop;
  2. use system_error::SystemError;
  3. use super::{multiboot2::early_multiboot2_init, pvh::early_linux32_pvh_init};
  4. const BOOT_ENTRY_TYPE_MULTIBOOT: u64 = 1;
  5. const BOOT_ENTRY_TYPE_MULTIBOOT2: u64 = 2;
  6. const BOOT_ENTRY_TYPE_LINUX_32: u64 = 3;
  7. const BOOT_ENTRY_TYPE_LINUX_64: u64 = 4;
  8. const BOOT_ENTRY_TYPE_LINUX_32_PVH: u64 = 5;
  9. #[derive(Debug)]
  10. #[repr(u64)]
  11. enum BootProtocol {
  12. Multiboot = 1,
  13. Multiboot2,
  14. Linux32,
  15. Linux64,
  16. Linux32Pvh,
  17. }
  18. impl TryFrom<u64> for BootProtocol {
  19. type Error = SystemError;
  20. fn try_from(value: u64) -> Result<Self, Self::Error> {
  21. match value {
  22. BOOT_ENTRY_TYPE_MULTIBOOT => Ok(BootProtocol::Multiboot),
  23. BOOT_ENTRY_TYPE_MULTIBOOT2 => Ok(BootProtocol::Multiboot2),
  24. BOOT_ENTRY_TYPE_LINUX_32 => Ok(BootProtocol::Linux32),
  25. BOOT_ENTRY_TYPE_LINUX_64 => Ok(BootProtocol::Linux64),
  26. BOOT_ENTRY_TYPE_LINUX_32_PVH => Ok(BootProtocol::Linux32Pvh),
  27. _ => Err(SystemError::EINVAL),
  28. }
  29. }
  30. }
  31. #[inline(never)]
  32. pub(super) fn early_boot_init(
  33. boot_entry_type: u64,
  34. arg1: u64,
  35. arg2: u64,
  36. ) -> Result<(), SystemError> {
  37. let boot_protocol = BootProtocol::try_from(boot_entry_type)?;
  38. match boot_protocol {
  39. BootProtocol::Multiboot2 => early_multiboot2_init(arg1 as u32, arg2),
  40. BootProtocol::Linux32 | BootProtocol::Linux64 | BootProtocol::Multiboot => loop {
  41. spin_loop();
  42. },
  43. BootProtocol::Linux32Pvh => early_linux32_pvh_init(arg2 as usize),
  44. }
  45. }