Add basic kernel loading
This commit is contained in:
@@ -1 +1,2 @@
|
||||
/target
|
||||
image
|
||||
|
||||
Generated
+5
@@ -1,5 +1,9 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "char16-literal"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "core-rt"
|
||||
version = "0.1.0"
|
||||
@@ -12,6 +16,7 @@ version = "0.1.0"
|
||||
name = "yboot2"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"char16-literal",
|
||||
"core-rt",
|
||||
"efi",
|
||||
]
|
||||
|
||||
+3
-3
@@ -7,6 +7,6 @@ edition = "2018"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
#spin = { version = "0.5.2" }
|
||||
efi = { path = "crates/efi" }
|
||||
core-rt = { path = "crates/core-rt" }
|
||||
efi = { path = "crates/efi" }
|
||||
char16-literal = { path = "crates/char16-literal" }
|
||||
core-rt = { path = "crates/core-rt" }
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "char16-literal"
|
||||
version = "0.1.0"
|
||||
authors = ["Mark <alnyan@airmail.cc>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
@@ -0,0 +1,64 @@
|
||||
use proc_macro::{
|
||||
TokenStream,
|
||||
TokenTree,
|
||||
Literal,
|
||||
Group,
|
||||
Delimiter,
|
||||
Punct,
|
||||
Spacing
|
||||
};
|
||||
|
||||
fn convert(input: &[u8]) -> Vec<u16> {
|
||||
// TODO: support escaping
|
||||
let mut iter = input.iter();
|
||||
let first = *iter.next().unwrap();
|
||||
let ch = if first == b'r' {
|
||||
*iter.next().unwrap()
|
||||
} else {
|
||||
first
|
||||
};
|
||||
|
||||
if ch != b'"' {
|
||||
panic!("Expected a string literal");
|
||||
}
|
||||
|
||||
// TODO: check for non-ascii?
|
||||
let mut vec = Vec::<u16>::new();
|
||||
for b in iter {
|
||||
if *b == b'"' {
|
||||
break;
|
||||
}
|
||||
vec.push(*b as u16);
|
||||
}
|
||||
vec.push(0);
|
||||
|
||||
vec
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn cstr16(input: TokenStream) -> TokenStream {
|
||||
use std::iter::FromIterator;
|
||||
|
||||
let s = input.into_iter().next().unwrap();
|
||||
match s {
|
||||
TokenTree::Literal(data) => {
|
||||
let text = data.to_string();
|
||||
let conv = convert(text.as_bytes());
|
||||
TokenStream::from_iter(vec![
|
||||
TokenTree::from(Punct::new('&', Spacing::Joint)),
|
||||
TokenTree::Group(Group::new(
|
||||
Delimiter::Bracket,
|
||||
TokenStream::from_iter(
|
||||
conv.iter().map(|word| {
|
||||
vec![
|
||||
TokenTree::from(Literal::u16_suffixed(*word)),
|
||||
TokenTree::from(Punct::new(',', Spacing::Joint)),
|
||||
]
|
||||
}).flatten()
|
||||
)
|
||||
))
|
||||
])
|
||||
},
|
||||
other => panic!("Unexpected {:?}", other)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
#![no_std]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use core::intrinsics::wrapping_sub;
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn memcpy(dst: *mut u8, src: *const u8, cnt: usize) -> *mut u8 {
|
||||
@@ -22,7 +25,7 @@ unsafe extern "C" fn memset(dst: *mut u8, val: i32, cnt: usize) -> *mut u8 {
|
||||
unsafe extern "C" fn memcmp(a: *const u8, b: *const u8, cnt: usize) -> i32 {
|
||||
let mut i = 0isize;
|
||||
while i < cnt as isize {
|
||||
let diff = *(a.offset(i)) - *(b.offset(i));
|
||||
let diff = wrapping_sub(*(a.offset(i)), *(b.offset(i)));
|
||||
if diff != 0u8 {
|
||||
return diff as i32;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use core::ffi::c_void;
|
||||
use core::fmt;
|
||||
|
||||
pub type Handle = *mut c_void;
|
||||
pub type Event = *mut c_void;
|
||||
@@ -84,3 +85,37 @@ pub struct Guid {
|
||||
pub data3: u16,
|
||||
pub data4: [u8; 8]
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct CStr16 {
|
||||
data: [u16]
|
||||
}
|
||||
|
||||
impl CStr16 {
|
||||
pub fn from_literal(data: &'static [u16]) -> &'static CStr16 {
|
||||
return unsafe {&*(data as *const _ as *const _)};
|
||||
}
|
||||
|
||||
pub fn as_ptr(&self) -> *const u16 {
|
||||
return &self.data[0]
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for CStr16 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "\"")?;
|
||||
<Self as fmt::Display>::fmt(self, f)?;
|
||||
write!(f, "\"")
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for CStr16 {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
for word in self.data.iter() {
|
||||
if *word != 0 {
|
||||
write!(f, "{}", *word as u8 as char)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@ impl MemoryDescriptor {
|
||||
pub fn end(&self) -> usize {
|
||||
return self.physical_start + (self.number_of_pages as usize) * 0x1000;
|
||||
}
|
||||
pub fn is_usable_now(&self) -> bool {
|
||||
return self._type == 7;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MemoryMapIterator<'a> {
|
||||
@@ -68,4 +71,20 @@ impl<'a> MemoryMap<'a> {
|
||||
count: self.size / self.descriptor_size
|
||||
});
|
||||
}
|
||||
|
||||
pub fn is_usable_now(&self, page: usize) -> bool {
|
||||
for item in self.iter().unwrap() {
|
||||
if item.is_usable_now() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let aligned_begin = (item.begin() + 0xFFF) & !0xFFF;
|
||||
let aligned_end = item.end() & !0xFFF;
|
||||
|
||||
if page >= aligned_begin && page < aligned_end {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+68
-15
@@ -1,35 +1,88 @@
|
||||
use crate::{Protocol, Guid};
|
||||
use crate::{Protocol, Guid, CStr16, Status};
|
||||
use core::ptr::null_mut;
|
||||
use core::ffi::c_void;
|
||||
// Use altlib's io module
|
||||
#[cfg(feature = "with-altlib")]
|
||||
use altlib::io;
|
||||
|
||||
pub const OPEN_MODE_READ: u64 = 1;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FileProtocol {
|
||||
revision: u64,
|
||||
open: *mut c_void,
|
||||
close: unsafe fn (*mut FileProtocol) -> u64,
|
||||
delete: *mut c_void,
|
||||
read: *mut c_void,
|
||||
write: *mut c_void,
|
||||
// ...
|
||||
revision: u64,
|
||||
open: unsafe fn (*const FileProtocol,
|
||||
*mut *mut FileProtocol,
|
||||
*const u16,
|
||||
u64, u64) -> u64,
|
||||
close: unsafe fn (*mut FileProtocol) -> u64,
|
||||
delete: *mut c_void,
|
||||
read: unsafe fn (*mut FileProtocol, *mut usize, *mut c_void) -> u64,
|
||||
write: *mut c_void,
|
||||
get_position: *mut c_void,
|
||||
set_position: unsafe fn (*mut FileProtocol, u64) -> u64,
|
||||
}
|
||||
|
||||
pub struct File<'a> {
|
||||
inner: &'a mut FileProtocol
|
||||
pub struct File {
|
||||
inner: *mut FileProtocol
|
||||
}
|
||||
|
||||
impl<'a> From<*mut FileProtocol> for File<'a> {
|
||||
fn from(proto: *mut FileProtocol) -> File<'a> {
|
||||
impl From<*mut FileProtocol> for File {
|
||||
fn from(proto: *mut FileProtocol) -> File {
|
||||
File {
|
||||
inner: unsafe { &mut *proto }
|
||||
inner: proto
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for File<'a> {
|
||||
impl Drop for File {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
(self.inner.close)(
|
||||
((*self.inner).close)(
|
||||
self.inner
|
||||
);
|
||||
}
|
||||
self.inner = null_mut();
|
||||
}
|
||||
}
|
||||
|
||||
impl File {
|
||||
pub fn open(&self, name: &CStr16, mode: u64, attr: u64) -> Result<File, Status> {
|
||||
let mut ptr: *mut FileProtocol = null_mut();
|
||||
match Status::from_num(unsafe {
|
||||
((*self.inner).open)(
|
||||
self.inner,
|
||||
&mut ptr,
|
||||
name.as_ptr(),
|
||||
mode,
|
||||
attr
|
||||
)
|
||||
}) {
|
||||
Status::Success => Ok(File::from(ptr)),
|
||||
err => Err(err)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, Status> {
|
||||
let mut len = buf.len();
|
||||
match Status::from_num(unsafe {
|
||||
((*self.inner).read)(
|
||||
self.inner,
|
||||
&mut len,
|
||||
buf as *mut _ as *mut _
|
||||
)
|
||||
}) {
|
||||
Status::Success => Ok(len),
|
||||
err => Err(err)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn seek(&mut self, pos: u64) -> Result<(), Status> {
|
||||
Status::from_num(unsafe {
|
||||
((*self.inner).set_position)(
|
||||
self.inner,
|
||||
pos
|
||||
)
|
||||
}).to_result()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
BIOS=/usr/share/edk2-ovmf/OVMF_CODE.fd
|
||||
IMAGE=target/x86_64-unknown-uefi/debug/image.fat32
|
||||
IMAGE=image/image.fat32
|
||||
TARGET=x86_64-unknown-uefi
|
||||
CONFIG=debug
|
||||
|
||||
set -e
|
||||
|
||||
mkdir -p image
|
||||
|
||||
cargo build -Z build-std=core
|
||||
|
||||
dd if=/dev/zero of=${IMAGE} bs=1M count=64
|
||||
mkfs.vfat -F32 ${IMAGE}
|
||||
mcopy -i ${IMAGE} target/x86_64-unknown-uefi/debug/yboot2.efi ::app.efi
|
||||
mcopy -i ${IMAGE} target/${TARGET}/${CONFIG}/yboot2.efi ::app.efi
|
||||
mcopy -i ${IMAGE} image/config.txt ::config.txt
|
||||
mcopy -i ${IMAGE} image/kernel.elf ::kernel.elf
|
||||
|
||||
qemu-system-x86_64 \
|
||||
-s \
|
||||
-serial stdio \
|
||||
-m 256 \
|
||||
-drive format=raw,file=$BIOS,readonly=on,if=pflash \
|
||||
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
use efi::{File, Status, CStr16, MemoryMap};
|
||||
use core::mem::{MaybeUninit, size_of};
|
||||
use crate::proto::LoadProtocol;
|
||||
|
||||
type Off = u64;
|
||||
type Addr = u64;
|
||||
type Half = u16;
|
||||
type Word = u32;
|
||||
type XWord = u64;
|
||||
type SHalf = i16;
|
||||
type SWord = i32;
|
||||
type SXWord = i64;
|
||||
|
||||
const PT_LOAD: Word = 1;
|
||||
|
||||
const SHT_PROGBITS: Word = 1;
|
||||
|
||||
const SHF_WRITE: XWord = 1 << 0;
|
||||
const SHF_ALLOC: XWord = 1 << 1;
|
||||
|
||||
#[repr(C)]
|
||||
struct Ehdr {
|
||||
ident: [u8; 16],
|
||||
_type: Half,
|
||||
machine: Half,
|
||||
version: Word,
|
||||
entry: Addr,
|
||||
phoff: Off,
|
||||
shoff: Off,
|
||||
flags: Word,
|
||||
ehsize: Half,
|
||||
phentsize: Half,
|
||||
phnum: Half,
|
||||
shentsize: Half,
|
||||
shnum: Half,
|
||||
shstrndx: Half
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct Shdr {
|
||||
name: Word,
|
||||
_type: Word,
|
||||
flags: XWord,
|
||||
addr: Addr,
|
||||
offset: Off,
|
||||
size: XWord,
|
||||
link: Word,
|
||||
info: Word,
|
||||
addralign: XWord,
|
||||
entsize: XWord
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct Phdr {
|
||||
_type: Word,
|
||||
offset: Off,
|
||||
vaddr: Addr,
|
||||
paddr: Addr,
|
||||
filesz: Word,
|
||||
memsz: Word,
|
||||
flags: Word,
|
||||
align: Word
|
||||
}
|
||||
|
||||
pub struct Object {
|
||||
file: File,
|
||||
ehdr: Ehdr,
|
||||
}
|
||||
|
||||
unsafe fn any_as_u8_slice<T: Sized>(p: &mut T) -> &mut [u8] {
|
||||
::core::slice::from_raw_parts_mut(
|
||||
(p as *mut T) as *mut u8,
|
||||
::core::mem::size_of::<T>(),
|
||||
)
|
||||
}
|
||||
|
||||
impl Object {
|
||||
// Reason: EFI autism
|
||||
pub fn open(root: &mut File, path: &CStr16) -> Result<Object, Status> {
|
||||
let mut obj = Object {
|
||||
file: root.open(path, efi::proto::fp::OPEN_MODE_READ, 0)?,
|
||||
ehdr: unsafe { MaybeUninit::uninit().assume_init() },
|
||||
};
|
||||
|
||||
// Load header
|
||||
obj.file.seek(0)?;
|
||||
obj.file.read(unsafe {any_as_u8_slice(&mut obj.ehdr)})?;
|
||||
|
||||
// Validate that this is ELF
|
||||
if &obj.ehdr.ident[0 .. 4] != [0x7F, b'E', b'L', b'F'] {
|
||||
return Err(Status::InvalidParameter);
|
||||
}
|
||||
|
||||
// Validate that bitness matches requested
|
||||
if obj.ehdr.ident[4] != 2 {
|
||||
return Err(Status::InvalidParameter);
|
||||
}
|
||||
|
||||
Ok(obj)
|
||||
}
|
||||
|
||||
fn read_phdr(&mut self, phdr: &mut Phdr, index: usize) -> Result<(), Status> {
|
||||
let off = self.ehdr.phoff + self.ehdr.phentsize as u64 * index as u64;
|
||||
self.file.seek(off)?;
|
||||
if self.file.read(unsafe { any_as_u8_slice(phdr) })? != size_of::<Phdr>() {
|
||||
Err(Status::Err)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
fn read_shdr(&mut self, shdr: &mut Shdr, index: usize) -> Result<(), Status> {
|
||||
let off = self.ehdr.shoff + self.ehdr.shentsize as u64 * index as u64;
|
||||
self.file.seek(off)?;
|
||||
if self.file.read(unsafe { any_as_u8_slice(shdr) })? != size_of::<Shdr>() {
|
||||
Err(Status::Err)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// Called after load()
|
||||
pub fn locate_protocol_data<T: LoadProtocol>(&mut self)
|
||||
-> Result<&'static mut T, Status>
|
||||
{
|
||||
let mut shdr = unsafe { MaybeUninit::<Shdr>::uninit().assume_init() };
|
||||
|
||||
for i in 0 .. self.ehdr.shnum {
|
||||
self.read_shdr(&mut shdr, i as usize)?;
|
||||
|
||||
if shdr._type == SHT_PROGBITS &&
|
||||
(shdr.flags & (SHF_ALLOC | SHF_WRITE)) == SHF_ALLOC | SHF_WRITE {
|
||||
if shdr.size as usize >= size_of::<T>() {
|
||||
// Make a physical address
|
||||
let ptr = shdr.addr - 0xFFFFFF0000000000;
|
||||
let magic: &[u8] = unsafe { core::slice::from_raw_parts(ptr as *const _, 8)};
|
||||
if magic == T::KERNEL_MAGIC {
|
||||
return Ok(unsafe { &mut *(ptr as *mut _) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(Status::InvalidParameter)
|
||||
}
|
||||
|
||||
pub fn load(&mut self, mmap: &MemoryMap) -> Result<usize, Status> {
|
||||
extern {
|
||||
fn memset(block: *mut u8, value: i32, count: usize) -> *mut u8;
|
||||
}
|
||||
|
||||
let mut phdr = unsafe { MaybeUninit::<Phdr>::uninit().assume_init() };
|
||||
|
||||
// 1. Check that all pages in load segments are usable
|
||||
for i in 0 .. self.ehdr.phnum {
|
||||
self.read_phdr(&mut phdr, i as usize)?;
|
||||
|
||||
if phdr._type == PT_LOAD {
|
||||
let start = phdr.paddr & !0xFFF;
|
||||
let end = (phdr.paddr + phdr.memsz as u64 + 0xFFF) & !0xFFF;
|
||||
|
||||
for addr in (start .. end).step_by(0x1000) {
|
||||
if !mmap.is_usable_now(addr as usize) {
|
||||
return Err(Status::InvalidParameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Load segments
|
||||
for i in 0 .. self.ehdr.phnum {
|
||||
self.read_phdr(&mut phdr, i as usize)?;
|
||||
|
||||
if phdr._type == PT_LOAD {
|
||||
// Load what's provided in ELF
|
||||
if phdr.filesz > 0 {
|
||||
let mut data = unsafe {core::slice::from_raw_parts_mut(
|
||||
phdr.paddr as *mut u8,
|
||||
phdr.filesz as usize,
|
||||
)};
|
||||
|
||||
self.file.seek(phdr.offset)?;
|
||||
self.file.read(&mut data)?;
|
||||
}
|
||||
|
||||
// Zero the rest
|
||||
if phdr.memsz > phdr.filesz {
|
||||
unsafe {
|
||||
memset((phdr.paddr as usize + phdr.filesz as usize) as *mut u8,
|
||||
0,
|
||||
(phdr.memsz - phdr.filesz) as usize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(self.ehdr.entry as usize - 0xFFFFFF0000000000)
|
||||
}
|
||||
}
|
||||
+38
-6
@@ -1,33 +1,65 @@
|
||||
#![feature(asm)]
|
||||
#![feature(asm,const_fn,rustc_private,compiler_builtins)]
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
extern crate efi;
|
||||
extern crate core_rt;
|
||||
#[macro_use]
|
||||
extern crate char16_literal;
|
||||
pub (crate) use char16_literal::cstr16;
|
||||
|
||||
use efi::{
|
||||
CStr16,
|
||||
Status,
|
||||
ConfigurationTableEntry,
|
||||
ImageHandle,
|
||||
SystemTable,
|
||||
system_table,
|
||||
image_handle
|
||||
image_handle,
|
||||
};
|
||||
|
||||
#[macro_use]
|
||||
mod println;
|
||||
mod proto;
|
||||
mod elf;
|
||||
|
||||
fn main() -> efi::Result<()> {
|
||||
let mut desc_array = [0u8; 4096];
|
||||
let mut mmap = efi::MemoryMap::new(&mut desc_array);
|
||||
let bs = &system_table().boot_services;
|
||||
let rs = &system_table().runtime_services;
|
||||
|
||||
bs.get_memory_map(&mut mmap)?;
|
||||
|
||||
let path = image_handle().get_boot_path()?;
|
||||
let root = path.open_partition()?;
|
||||
let rsdp = system_table()
|
||||
.config_iter()
|
||||
.find(|x| matches!(x, ConfigurationTableEntry::Acpi10Table(_)))
|
||||
.map(|x| match x {
|
||||
ConfigurationTableEntry::Acpi10Table(ptr) => ptr,
|
||||
_ => panic!()
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
Ok(())
|
||||
let mut root = image_handle().get_boot_path()?.open_partition()?;
|
||||
let mut obj = elf::Object::open(&mut root, CStr16::from_literal(cstr16!(r"\kernel.elf")))?;
|
||||
let entry = obj.load(&mmap)?;
|
||||
let data = obj.locate_protocol_data::<proto::V1>()?;
|
||||
|
||||
// TODO: load initrd
|
||||
|
||||
// Get the new memory map and terminate boot services
|
||||
bs.get_memory_map(&mut mmap)?;
|
||||
bs.exit_boot_services(mmap.key)?;
|
||||
|
||||
use proto::LoadProtocol;
|
||||
data.set_mmap(&mmap);
|
||||
data.set_initrd(0, 0);
|
||||
data.set_acpi_rsdp(rsdp as usize);
|
||||
data.set_loader_magic();
|
||||
|
||||
unsafe {
|
||||
let entry_fn: unsafe fn () -> ! = core::mem::transmute(entry);
|
||||
entry_fn();
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
use core::convert::TryInto;
|
||||
use efi::MemoryMap;
|
||||
|
||||
const CMDLINE_SIZE: usize = 256;
|
||||
|
||||
pub trait LoadProtocol: Sized {
|
||||
const KERNEL_MAGIC: [u8; 8];
|
||||
|
||||
fn set_loader_magic(&mut self);
|
||||
fn set_mmap(&mut self, map: &MemoryMap);
|
||||
fn set_initrd(&mut self, base: usize, size: usize);
|
||||
fn set_acpi_rsdp(&mut self, rsdp: usize);
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Header {
|
||||
kernel_magic: [u8; 8],
|
||||
loader_magic: [u8; 8]
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct V1 {
|
||||
hdr: Header,
|
||||
|
||||
memory_map_data: u64,
|
||||
memory_map_size: u32,
|
||||
memory_map_entsize: u32,
|
||||
|
||||
video_width: u32,
|
||||
video_height: u32,
|
||||
video_format: u32,
|
||||
_pad0: u32,
|
||||
video_framebuffer: u64,
|
||||
video_pitch: u64,
|
||||
|
||||
elf_symtab_hdr: u64,
|
||||
elf_symtab_data: u64,
|
||||
elf_strtab_hdr: u64,
|
||||
elf_strtab_data: u64,
|
||||
|
||||
initrd_base: u64,
|
||||
initrd_size: u64,
|
||||
|
||||
rsdp: u64,
|
||||
|
||||
cmdline: [u8; CMDLINE_SIZE]
|
||||
}
|
||||
|
||||
impl LoadProtocol for V1 {
|
||||
const KERNEL_MAGIC: [u8; 8] = [
|
||||
0x07, 0xB0, 0x07, 0xB0, 0xA9, 0x97, 0xA1, 0x00
|
||||
];
|
||||
|
||||
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 set_mmap(&mut self, map: &MemoryMap) {
|
||||
self.memory_map_data = (map.storage_ref.as_ptr() as usize).try_into().unwrap();
|
||||
self.memory_map_size = map.size.try_into().unwrap();
|
||||
self.memory_map_entsize = map.descriptor_size.try_into().unwrap();
|
||||
}
|
||||
|
||||
fn set_initrd(&mut self, base: usize, size: usize) {
|
||||
self.initrd_base = base.try_into().unwrap();
|
||||
self.initrd_size = size.try_into().unwrap();
|
||||
}
|
||||
|
||||
fn set_acpi_rsdp(&mut self, rsdp: usize) {
|
||||
self.rsdp = rsdp.try_into().unwrap();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user