Implement loader protocol for ProtoV1

This commit is contained in:
Mark 2020-09-21 13:35:04 +03:00
parent 56af34c505
commit 20841c7ef2
6 changed files with 116 additions and 48 deletions

8
src/kernel.rs Normal file
View File

@ -0,0 +1,8 @@
#[cfg(feature = "kernel-protocol")]
impl KernelProtocol for ProtoV1 {
const KERNEL_MAGIC: [u8; 8] = [
0x07, 0xB0, 0x07, 0xB0, 0xA9, 0x97, 0xA1, 0x00
];
}

View File

@ -3,16 +3,23 @@
pub mod mmap;
pub mod video;
use video::VideoInfo;
use mmap::MemoryMapInfo;
#[cfg(feature = "load-protocol")]
pub mod load;
#[cfg(feature = "kernel-protocol")]
pub mod kernel;
pub mod v1;
pub const CMDLINE_SIZE: usize = 256;
pub use v1::ProtoV1;
pub use video::VideoInfo;
pub use mmap::MemoryMapInfo;
pub const FLAG_VIDEO: u32 = 1 << 0;
pub const FLAG_INITRD: u32 = 1 << 1;
pub const FLAG_UPPER: u32 = 1 << 2;
pub trait LoadProtocol: Sized {
fn set_loader_magic(&mut self);
pub enum Error {
BufferTooSmall,
Error
}
pub trait KernelProtocol: Sized {
@ -31,46 +38,3 @@ pub struct ElfTables {
pub strtab_hdr: u64,
pub strtab_data: u64,
}
#[repr(C)]
pub struct ProtoV1 {
pub hdr: Header,
pub flags: u32,
pub video: VideoInfo,
pub memory_map: MemoryMapInfo,
pub elf_tables: ElfTables,
pub initrd_base: u64,
pub initrd_size: u64,
pub rsdp: u64,
pub cmdline: [u8; CMDLINE_SIZE]
}
impl LoadProtocol for ProtoV1 {
fn set_loader_magic(&mut self) {
const LOADER_MAGIC: [u8; 8] = [
0x1A, 0x79, 0x9A, 0x0B, 0x70, 0x0B, 0x70, 0x00
];
self.hdr.loader_magic = LOADER_MAGIC;
}
}
impl KernelProtocol for ProtoV1 {
const KERNEL_MAGIC: [u8; 8] = [
0x07, 0xB0, 0x07, 0xB0, 0xA9, 0x97, 0xA1, 0x00
];
}
impl MemoryMapInfo {
// TODO: MemoryMapInfo with kernel-owned storage
pub fn by_loader() -> MemoryMapInfo {
MemoryMapInfo {
address: 0,
size: 0,
entsize: 0,
}
}
}

64
src/load.rs Normal file
View File

@ -0,0 +1,64 @@
use core::convert::TryInto;
use crate::{Error, VideoInfo, MemoryMapInfo, ProtoV1};
pub trait LoadProtocol: Sized {
fn get_video_info(&self) -> &VideoInfo;
fn set_video_info(&mut self, info: &VideoInfo);
fn set_mmap(&mut self, mmap: &MemoryMapInfo) -> Result<(), Error>;
fn set_acpi_rsdp(&mut self, phys_addr: usize);
fn set_initrd(&mut self, phys_addr: usize, size: usize);
fn set_loader_magic(&mut self);
}
impl LoadProtocol for ProtoV1 {
fn set_loader_magic(&mut self) {
const LOADER_MAGIC: [u8; 8] = [
0x1A, 0x79, 0x9A, 0x0B, 0x70, 0x0B, 0x70, 0x00
];
self.hdr.loader_magic = LOADER_MAGIC;
}
fn get_video_info(&self) -> &VideoInfo {
&self.video
}
fn set_video_info(&mut self, info: &VideoInfo) {
self.video = *info;
}
fn set_mmap(&mut self, map: &MemoryMapInfo) -> Result<(), Error> {
let ptr = map.address as *const u8;
if self.memory_map.size == 0 || self.memory_map.address == 0 {
// Memory map pointer is stored
if ptr >= 0x100000000 as *const _ {
panic!("Memory map pointer crosses 4GiB");
}
self.memory_map.address = map.address;
} else {
if map.size > self.memory_map.size {
panic!("Can't fit memory map");
}
unsafe {
extern "C" {
fn memcpy(dst: *mut u8, src: *const u8, count: usize) -> *mut u8;
}
memcpy(self.memory_map.address as *mut _, ptr, map.size as usize);
}
}
self.memory_map.size = map.size;
self.memory_map.entsize = map.entsize;
Err(Error::BufferTooSmall)
}
fn set_initrd(&mut self, base: usize, size: usize) {
if self.initrd_base + self.initrd_size >= 0x100000000 {
panic!("Initrd crosses 4GiB");
}
self.initrd_base = base.try_into().unwrap();
self.initrd_size = size.try_into().unwrap();
}
fn set_acpi_rsdp(&mut self, addr: usize) {
self.rsdp = addr as u64;
}
}

View File

@ -3,3 +3,14 @@ pub struct MemoryMapInfo {
pub size: u32,
pub entsize: u32
}
impl MemoryMapInfo {
// TODO: MemoryMapInfo with kernel-owned storage
pub fn by_loader() -> MemoryMapInfo {
MemoryMapInfo {
address: 0,
size: 0,
entsize: 0,
}
}
}

20
src/v1.rs Normal file
View File

@ -0,0 +1,20 @@
use crate::{VideoInfo, Header, MemoryMapInfo, ElfTables};
pub const CMDLINE_SIZE: usize = 256;
#[repr(C)]
pub struct ProtoV1 {
pub hdr: Header,
pub flags: u32,
pub video: VideoInfo,
pub memory_map: MemoryMapInfo,
pub elf_tables: ElfTables,
pub initrd_base: u64,
pub initrd_size: u64,
pub rsdp: u64,
pub cmdline: [u8; CMDLINE_SIZE]
}

View File

@ -9,6 +9,7 @@ pub enum PixelFormat {
Text,
}
#[derive(Clone, Copy)]
pub struct VideoInfo {
pub width: u32,
pub height: u32,