aphrodite/multiboot2.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
//! Definitions of structs for multiboot2 information. Mostly used during pre-userspace.
/// Used for Multiboot2 tags. This shouldn't be used after a [crate::boot::BootInfo] struct has been initalized, but it still can be used.
#[repr(C)]
#[derive(Clone)]
pub struct Tag {
/// The type of the tag.
pub tag_type: u32,
/// The length of the tag.
pub tag_len: u32
}
/// The root tag. The official Multiboot2 name is literally the "fixed part" of the tags, so I made a better name.
#[repr(C)]
#[derive(Clone)]
pub struct RootTag {
/// The total length between the root tag and the terminating tag.
/// You can also search for the tag that has a type of 0 and a length of 8.
pub total_len: u32,
/// Reserved space. Unused for anything.
reserved: u32,
}
/// A Multiboot2 module. See <https://aphrodite-os.github.io/book/bootloader-modules.html>.
#[derive(Clone)]
pub struct Module {
/// A pointer to the start of the module
pub mod_start: *const u8,
/// A pointer to the end of the module
pub mod_end: *const u8,
/// A string that should be in the format `module_name (command line arguments)`.
/// See <https://aphrodite-os.github.io/book/bootloader-modules.html>.
pub mod_str: &'static core::ffi::CStr
}
/// One memory section provided by a Multiboot2 bootloader.
#[repr(C)]
#[derive(Clone)]
pub struct MemorySection {
/// The base address of the section.
pub base_addr: u64,
/// The length of the section.
pub length: u64,
/// The type of the section. Name is changed from the one provided in the Multiboot2 docs
/// as "type" is a keyword in rust.
pub mem_type: u32,
/// Reserved space. Should be ignored.
reserved: u32,
}
impl crate::boot::MemoryMapping for MemorySection {
fn get_type(&self) -> crate::boot::MemoryType {
match self.mem_type {
1 => crate::boot::MemoryType::Free,
2 => crate::boot::MemoryType::HardwareReserved,
3 => crate::boot::MemoryType::HardwareSpecific(3, false),
5 => crate::boot::MemoryType::Faulty,
_ => crate::boot::MemoryType::Reserved
}
}
fn get_start(&self) -> u64 {
self.base_addr
}
fn get_length(&self) -> u64 {
self.length
}
}
/// The raw memory map provided by a Multiboot2 bootloader. This is interpreted
/// into a [MemoryMap].
#[repr(C)]
pub struct RawMemoryMap {
/// The type of the tag.
pub tag_type: u32,
/// The length of the tag.
pub tag_len: u32,
/// Size of one entry(one [MemorySection] for Aphrodite)
pub entry_size: u32,
/// The version of the memory map. Should be disregarded as it's 0.
pub entry_version: u32, // currently is 0, future Multiboot2 versions may increment
/// The sections. This is the reason that [Clone] can't be implemented for [RawMemoryMap].
pub sections: [MemorySection]
}
/// A full memory map provided by a Multiboot2 bootloader.
#[derive(Clone, Copy)]
pub struct MemoryMap {
/// The version of the memory map. Should be disregarded as it's 0.
pub version: u32, // currently is 0, future Multiboot2 versions may increment
/// Size of one entry(one [MemorySection] for Aphrodite)
pub entry_size: u32,
/// All sections.
pub sections: &'static [MemorySection],
/// Iterator's index.
pub idx: usize,
}
impl crate::boot::MemoryMap for MemoryMap {}
impl crate::boot::_MemoryMap for MemoryMap {
fn len(&self) -> usize {
self.sections.len()
}
}
impl core::ops::Index<usize> for MemoryMap {
type Output = dyn crate::boot::MemoryMapping;
fn index(&self, index: usize) -> &Self::Output {
&self.sections[index] as &'static dyn crate::boot::MemoryMapping
}
}
impl core::iter::Iterator for MemoryMap {
type Item = &'static dyn crate::boot::MemoryMapping;
fn next(&mut self) -> Option<Self::Item> {
self.idx += 1;
if self.sections.len()<=self.idx-1 {
return None;
}
Some(&self.sections[self.idx-1])
}
}
/// A color descriptor for [ColorInfo::Palette].
#[repr(C)]
#[derive(Clone, Copy)]
pub struct PaletteColorDescriptor {
/// The red value
pub red: u8,
/// The green value
pub green: u8,
/// The blue value
pub blue: u8
}
/// Information about color, for use in [FramebufferInfo].
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum ColorInfo {
/// The palette for use on the framebuffer.
Palette {
/// The number of colors in the palette.
num_colors: u32,
/// The first color in the palette.
palette: *const PaletteColorDescriptor
},
/// RGB information for use on the framebuffer.
RGBColor {
/// Red color information.
red_field_position: u8,
/// See above.
red_mask_size: u8,
/// Green color information.
green_field_position: u8,
/// See above.
green_mask_size: u8,
/// Blue color information.
blue_field_position: u8,
/// See above.
blue_mask_size: u8,
},
/// Text information, no metadata
EGAText
}
/// Information about the framebuffer.
#[repr(C)]
#[derive(Clone)]
pub struct FramebufferInfo {
/// A pointer to the framebuffer.
pub address: u64,
/// The pitch of the framebuffer (i.e. the number of bytes in each row).
pub pitch: u32,
/// The width of the framebuffer.
pub width: u32,
/// The height of the framebuffer.
pub height: u32,
/// Bits per pixel.
pub bpp: u8,
/// The type of the framebuffer. 0=indexed, 1=RGB, 2=text.
pub fb_type: u8,
/// Reserved space. Ignore.
reserved: u8,
// Color info after this; we need separate structs for each colorinfo as
// we have to understand the format the bootloader gives us.
}
/// Boot info collected from provided [Tag]s.
#[derive(Clone)]
pub struct Multiboot2BootInfo {
/// See <https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html#Basic-memory-information>.
/// Tl;dr: mem_lower indicates the amount of "lower memory"
/// and mem_upper the amount of "upper memory".
pub mem_lower: Option<u32>,
/// See above
pub mem_upper: Option<u32>,
// Multiboot2 bootloaders may provide us with the BIOS device and partition, but we're not interested.
// To ensure future developers don't get any ideas, I'm leaving it out here.
// If you need it, good luck.
/// We're provided with a C-style UTF-8(null-terminated UTF-8) string. This should contain the original pointer provided by
/// the bootloader.
/// See <https://aphrodite-os.github.io/book/command-line.html> for the format.
pub cmdline: Option<&'static core::ffi::CStr>,
// Due to the way modules work, it's not easily possible to make a struct that contains all the modules.
// Therefore, they are loaded on the fly.
// Multiboot2 bootloaders may provide us with ELF symbols, but I'm feeling lazy and right now it's mostly
// unnecessary, so I don't care. Sorry if you are affected by this.
/// The memory map provided by the bootloader.
pub memory_map: Option<MemoryMap>,
/// The name of the bootloader(for example, "GRUB 2.12"). C-style UTF-8(null-terminated UTF-8) string.
/// This should contain the original pointer provided by the bootloader.
pub bootloader_name: Option<&'static core::ffi::CStr>,
// APM table is ignored as APM has been superseded by ACPI. If your system doesn't support ACPI, good luck.
// VBE table is ignored for a similar reason to above: it's deprecated. Good luck if you need it.
/// Provides information on the framebuffer.
pub framebuffer_info: Option<FramebufferInfo>,
/// Color info, stored separately from [FramebufferInfo] because rust
pub color_info: Option<ColorInfo>,
// Even though SMBIOS is documented for Multiboot2, we're not using it and will instead search for it ourselves.
// This is because right now I cannot figure out what format it provides the SMBIOS table in.
// EFI memory map and image handle pointers are not included for portability.
// "Image load base physical address" is not included as at the moment the kernel is not relocatable.
}