Skip to main content

proka_exec/
header.rs

1//! The header definitions.
2use crate::HEADER_SIZE;
3
4/// The magic number, fixed to 'PKEX'
5pub const PKEX_MAGIC: u32 = 0x58454B50;
6
7/// The main header struct, which contains the metadata of the PKE file.
8#[repr(C, packed)]
9#[derive(Debug, Clone, Copy)]
10pub struct Header {
11    /// The magic number, fixed to 'PKEX'
12    pub magic: u32,
13
14    /// The minimal kernel version supported.
15    ///
16    /// # Note
17    /// As the `proka-bootloader`'s definitions, its format is similar
18    /// like `[major, minor, fix]`. See `proka-bootloader` crate for more informations.
19    pub min: [u16; 3],
20
21    /// The maximum kernel supported.
22    ///
23    /// For notes, see above.
24    pub max: [u16; 3],
25
26    /// Signates is this executable run as `userapp` or `coredrv`.
27    pub mode: ExecMode,
28
29    /// The section table count.
30    pub sections: u16,
31
32    /// The section which contains the entry point.
33    pub entry_sec: u16,
34
35    /// The entry offset of the section.
36    pub entry_off: u32,
37
38    /// The author name (max length is 32 bytes).
39    pub author: [u8; 32],
40
41    /// The executable/project name.
42    pub name: [u8; 32],
43
44    /// Extended bits for different mode parsing (reserved).
45    pub extended: [u8; 36],
46}
47
48impl Default for Header {
49    fn default() -> Self {
50        Self::new()
51    }
52}
53
54impl Header {
55    /// Create a header object.
56    pub fn new() -> Self {
57        Self {
58            magic: PKEX_MAGIC,
59            min: [0; 3],
60            max: [0; 3],
61            mode: ExecMode::UserApp,
62            sections: 0,
63            entry_sec: 0,
64            entry_off: HEADER_SIZE as u32,
65            author: [0; 32],
66            name: [0; 32],
67            extended: [0u8; 36],
68        }
69    }
70
71    /// Validate is this a valid proka executable.
72    #[inline]
73    pub fn validate(&self) -> bool {
74        self.magic == PKEX_MAGIC
75    }
76
77    /// Convert this header to array
78    #[inline]
79    pub const fn to_array(&self) -> [u8; HEADER_SIZE] {
80        // SAFETY: used `#[repr(C)]`
81        unsafe { core::ptr::read(self as *const Self as *const [u8; HEADER_SIZE]) }
82    }
83}
84
85/// The executable mode.
86#[repr(C)]
87#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
88pub enum ExecMode {
89    /// Run in `userapp` mode (Ring 3).
90    #[default]
91    UserApp,
92
93    /// Run in `coredrv` mode (Ring 0).
94    CoreDrv,
95}
96
97// Tests
98#[cfg(test)]
99mod tests {
100    use super::*;
101
102    #[test]
103    fn test_header_length() {
104        assert_eq!(crate::HEADER_SIZE, 128);
105        assert_eq!(core::mem::size_of::<Header>(), 128)
106    }
107}