Implement loader protocol for ProtoV1
This commit is contained in:
parent
56af34c505
commit
20841c7ef2
8
src/kernel.rs
Normal file
8
src/kernel.rs
Normal 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
|
||||
];
|
||||
}
|
||||
|
60
src/lib.rs
60
src/lib.rs
@ -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
64
src/load.rs
Normal 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;
|
||||
}
|
||||
}
|
||||
|
11
src/mmap.rs
11
src/mmap.rs
@ -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
20
src/v1.rs
Normal 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]
|
||||
}
|
@ -9,6 +9,7 @@ pub enum PixelFormat {
|
||||
Text,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct VideoInfo {
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
|
Loading…
x
Reference in New Issue
Block a user