Implement iterator for the memory map

This commit is contained in:
Mark Poliakov 2023-11-06 10:40:09 +02:00
parent acfb360e07
commit 346e3e0ac8
4 changed files with 189 additions and 0 deletions

65
Cargo.lock generated Normal file
View File

@ -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",
]

View File

@ -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 = []

View File

@ -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<Item = &'a Self::Entry> + 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;
}

81
src/v1.rs Normal file
View File

@ -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::<AvailableMemoryRegion>()
}
}