multiboot2/
image_load_addr.rs

1//! Module for [`ImageLoadPhysAddrTag`].
2
3use crate::TagType;
4use crate::tag::TagHeader;
5#[cfg(feature = "builder")]
6use core::mem::size_of;
7use multiboot2_common::{MaybeDynSized, Tag};
8
9/// The physical load address tag. Typically, this is only available if the
10/// binary was relocated, for example if the relocatable header tag was
11/// specified.
12#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
13#[repr(C, align(8))]
14pub struct ImageLoadPhysAddrTag {
15    header: TagHeader,
16    load_base_addr: u32,
17}
18
19impl ImageLoadPhysAddrTag {
20    const BASE_SIZE: usize = size_of::<TagHeader>() + size_of::<u32>();
21
22    /// Constructs a new tag.
23    #[must_use]
24    pub fn new(load_base_addr: u32) -> Self {
25        Self {
26            header: TagHeader::new(Self::ID, Self::BASE_SIZE as u32),
27            load_base_addr,
28        }
29    }
30
31    /// Returns the load base address.
32    #[must_use]
33    pub const fn load_base_addr(&self) -> u32 {
34        self.load_base_addr
35    }
36}
37impl MaybeDynSized for ImageLoadPhysAddrTag {
38    type Header = TagHeader;
39
40    const BASE_SIZE: usize = size_of::<Self>();
41
42    fn dst_len(_: &TagHeader) {}
43}
44
45impl Tag for ImageLoadPhysAddrTag {
46    type IDType = TagType;
47
48    const ID: TagType = TagType::LoadBaseAddr;
49}
50
51#[cfg(all(test, feature = "builder"))]
52mod tests {
53    use super::ImageLoadPhysAddrTag;
54
55    const ADDR: u32 = 0xABCDEF;
56
57    #[test]
58    fn test_build_load_addr() {
59        let tag = ImageLoadPhysAddrTag::new(ADDR);
60        assert_eq!(tag.load_base_addr(), ADDR);
61    }
62}