address.rs 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. use crate::{HeaderTagFlag, HeaderTagHeader, HeaderTagType};
  2. use core::mem::size_of;
  3. /// This information does not need to be provided if the kernel image is in ELF
  4. /// format, but it must be provided if the image is in a.out format or in some
  5. /// other format. Required for legacy boot (BIOS).
  6. /// Determines load addresses.
  7. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
  8. #[repr(C)]
  9. pub struct AddressHeaderTag {
  10. header: HeaderTagHeader,
  11. /// Contains the address corresponding to the beginning of the Multiboot2 header — the physical memory location at which the magic value is supposed to be loaded. This field serves to synchronize the mapping between OS image offsets and physical memory addresses.
  12. header_addr: u32,
  13. /// Contains the physical address of the beginning of the text segment. The offset in the OS image file at which to start loading is defined by the offset at which the header was found, minus (header_addr - load_addr). load_addr must be less than or equal to header_addr.
  14. ///
  15. /// Special value -1 means that the file must be loaded from its beginning.
  16. load_addr: u32,
  17. /// Contains the physical address of the end of the data segment. (load_end_addr - load_addr) specifies how much data to load. This implies that the text and data segments must be consecutive in the OS image; this is true for existing a.out executable formats. If this field is zero, the boot loader assumes that the text and data segments occupy the whole OS image file.
  18. load_end_addr: u32,
  19. /// Contains the physical address of the end of the bss segment. The boot loader initializes this area to zero, and reserves the memory it occupies to avoid placing boot modules and other data relevant to the operating system in that area. If this field is zero, the boot loader assumes that no bss segment is present.
  20. bss_end_addr: u32,
  21. }
  22. impl AddressHeaderTag {
  23. /// Constructs a new tag.
  24. #[must_use]
  25. pub const fn new(
  26. flags: HeaderTagFlag,
  27. header_addr: u32,
  28. load_addr: u32,
  29. load_end_addr: u32,
  30. bss_end_addr: u32,
  31. ) -> Self {
  32. let header = HeaderTagHeader::new(HeaderTagType::Address, flags, size_of::<Self>() as u32);
  33. Self {
  34. header,
  35. header_addr,
  36. load_addr,
  37. load_end_addr,
  38. bss_end_addr,
  39. }
  40. }
  41. /// Returns the [`HeaderTagType`].
  42. #[must_use]
  43. pub const fn typ(&self) -> HeaderTagType {
  44. self.header.typ()
  45. }
  46. /// Returns the [`HeaderTagFlag`]s.
  47. #[must_use]
  48. pub const fn flags(&self) -> HeaderTagFlag {
  49. self.header.flags()
  50. }
  51. /// Returns the size.
  52. #[must_use]
  53. pub const fn size(&self) -> u32 {
  54. self.header.size()
  55. }
  56. /// Returns the header address.
  57. #[must_use]
  58. pub const fn header_addr(&self) -> u32 {
  59. self.header_addr
  60. }
  61. /// Returns the load begin address.
  62. #[must_use]
  63. pub const fn load_addr(&self) -> u32 {
  64. self.load_addr
  65. }
  66. /// Returns the load end address.
  67. #[must_use]
  68. pub const fn load_end_addr(&self) -> u32 {
  69. self.load_end_addr
  70. }
  71. /// Returns the bss end address.
  72. #[must_use]
  73. pub const fn bss_end_addr(&self) -> u32 {
  74. self.bss_end_addr
  75. }
  76. }
  77. #[cfg(test)]
  78. mod tests {
  79. use crate::AddressHeaderTag;
  80. #[test]
  81. fn test_assert_size() {
  82. assert_eq!(
  83. core::mem::size_of::<AddressHeaderTag>(),
  84. 2 + 2 + 4 + 4 + 4 + 4 + 4
  85. );
  86. }
  87. }