From 346e3e0ac818aa34dc3e165242a244ba60f96af6 Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Mon, 6 Nov 2023 10:40:09 +0200 Subject: [PATCH] Implement iterator for the memory map --- Cargo.lock | 65 +++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 6 ++++ src/lib.rs | 37 +++++++++++++++++++++++++ src/v1.rs | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 189 insertions(+) create mode 100644 Cargo.lock create mode 100644 src/v1.rs diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..09f30391 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,65 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bytemuck" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "2.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "yboot-proto" +version = "0.1.0" +dependencies = [ + "bytemuck", +] diff --git a/Cargo.toml b/Cargo.toml index 5da89265..feb2e8a7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,3 +6,9 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +bytemuck = { version = "1.13.1", features = ["derive"] } + +[features] +default = [] +dep-of-kernel = [] +dep-of-yboot = [] diff --git a/src/lib.rs b/src/lib.rs index 0c9ac1ac..72c0e16b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1 +1,38 @@ +#![feature(const_mut_refs)] #![no_std] + +use bytemuck::{Pod, Zeroable}; + +pub mod v1; + +pub use v1::LoadProtocol as LoadProtocolV1; + +pub const KERNEL_MAGIC: u32 = 0x1A2B3C4D; +pub const LOADER_MAGIC: u32 = 0xD4C3B2A1; +pub const PROTOCOL_VERSION_1: u32 = 1; + +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct LoadProtocolHeader { + pub kernel_magic: u32, + pub version: u32, +} + +pub trait AvailableRegion { + fn start_address(&self) -> usize; + fn page_count(&self) -> usize; +} + +pub trait IterableMemoryMap<'a> { + type Entry: AvailableRegion + 'a; + type Iter: Iterator + Clone; + + fn iter(&self) -> Self::Iter { + self.iter_with_offset(0) + } + + fn iter_with_offset(&self, offset: usize) -> Self::Iter; + + fn data_physical_base(&self) -> usize; + fn data_size(&self) -> usize; +} diff --git a/src/v1.rs b/src/v1.rs new file mode 100644 index 00000000..5bf1290b --- /dev/null +++ b/src/v1.rs @@ -0,0 +1,81 @@ +use core::mem::size_of; + +use bytemuck::{Pod, Zeroable}; + +use crate::{AvailableRegion, IterableMemoryMap, LoadProtocolHeader}; + +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct LoadProtocol { + pub header: LoadProtocolHeader, + pub kernel_virt_offset: u64, + + pub memory_map: MemoryMap, + + pub rsdp_address: u64, + pub initrd_address: u64, + pub initrd_size: u64, + + // Load options + pub opt_framebuffer: FramebufferOption, +} + +#[derive(Clone, Copy, Debug)] +#[repr(C)] +pub struct AvailableMemoryRegion { + pub start_address: u64, + pub page_count: u64, +} + +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct MemoryMap { + pub address: u64, + pub len: u64, +} + +// TODO specify format etc. +#[derive(Clone, Copy, Pod, Zeroable)] +#[repr(C)] +pub struct FramebufferOption { + pub req_width: u32, + pub req_height: u32, + + pub res_width: u32, + pub res_height: u32, + pub res_stride: u64, + pub res_address: u64, + pub res_size: u64, +} + +impl AvailableRegion for AvailableMemoryRegion { + fn start_address(&self) -> usize { + self.start_address as _ + } + + fn page_count(&self) -> usize { + self.page_count as _ + } +} + +impl IterableMemoryMap<'static> for MemoryMap { + type Entry = AvailableMemoryRegion; + type Iter = core::slice::Iter<'static, AvailableMemoryRegion>; + + fn iter_with_offset(&self, offset: usize) -> Self::Iter { + let virt_address = self.address + offset as u64; + let slice = unsafe { + core::slice::from_raw_parts(virt_address as *const AvailableMemoryRegion, self.len as _) + }; + + slice.iter() + } + + fn data_physical_base(&self) -> usize { + self.address as _ + } + + fn data_size(&self) -> usize { + self.len as usize * size_of::() + } +}